
Skull, 40000 faces
The little download counter on my super secret world domination dashboard indicates that my thesis code implementations of rendering suggestive contours on 3d meshes has been downloaded over a hundred times. Which tickles my curiosity.
If you’re doing anything fun, serious, silly (or can’t get the damn thing to work at all) with any of my implementations, don’t hesitate to drop me a line. After shedding tears, sweat, blood and probably various other bodily fluids over those implementations during the last year, it would be great to see them ending up in something awesome.
Today I found a way to render the shadow volumes used in the stencil buffer technique I posted about yesterday in Ogre3D. Sometimes all you need is a ninja and three penguins to get a good insight. These are the shadow maps for one single point light source. Notice how the ninja’s katana extends the shadow volume significantly, and how the intersections of the shadow volume with the objects themselves define self-shadowing. Not shown in the picture is how the shadow volumes extend to infinity: this is necessary to be able to use Carmack’s Reverse.

I’ve spent the day reading up on shadowing techniques for real-time rendering which can be used in the Ogre3D project I’m working on. I was not familiar with the details of the shadow volume method using stencil maps. It’s actually pretty clever, and it’s interesting to read how John Carmack (ID Software) developed the depth-fail-method (also known as Carmack’s Reverse) to be able to use the stencil shadow technique in scenes where the player/camera was inside the shadow volume. This is how they established the shadows of those things creeping up behind you in Doom 3.
Here’s a comparison I performed in Ogre3D:

Some good resources (some outdated, but the basics still apply):
I’m working my way through Ogre3D at the moment, to freshen up my C++/Visual Studio skills. I got my student copy from DreamSpark : seems that I’m still registered as a student, and thus qualified for free software - Yoink!. Browsing through the samples, I thought this was a nice touch: the SDK includes an ASCII shader (made in CG), sampling a 3D ASCII cube for values. It seems like a totally backwards way to approach rendering, but I like the silliness of it.
What I’ll be doing with this engine is still a bit uncertain. I’m thinking about implementing my GPU-accelerated technique to draw suggestive contours, cooking up a game from scratch (an educative experience), … we’ll see where it leads!
Here are some PBRT renders I made, to compare between using photon mapping and using regular raybouncing. I recompiled PBRT with the advanced Photon Mapping Integrator (C++ code available here) to speed up the Final Gathering algorithm. There’s still a lot of noise in the final image, but the caustics are clearly visible.

I’ve also made a (failed) attempt at subsurface scattering, but it’s a nice render anyway:

Today, I managed to perform contour/suggestive contour rendering in imagespace – thus working on a rendered diffuse shaded image. After using the Sobel edge detection filter to detect regular contours, I looked for an efficient algorithm to detect valleys and creases, in order to draw suggestive contours as well.
As the original paper from D. Decarlo indicates, I needed to exploit the fact that the algorithm should just work for smooth rendered images, whereas most valley detection algorithms are complicated because they provide noise robustness.
While a pixel in a valley is not necessarily the minimum intensity value in a neighborhood, it will be among a thin set of dark pixels that cuts across the neighborhood.If the valley is steep, the neighborhood will also contain significantly brighter pixels away from the valley; We can require a sufficient intensity difference that the surface must be turned meaningfully away.
The good news is that this method also detects regular contours, thus eliminating the need for the seperate sobel filter pass! GLSL code and results behind the cut.
Continue reading »
Using Vertex Buffer Objects to transfer my mesh data (vertices, normals, curvatures) directly into GPU memory using STATIC_DRAW_ARB pointers just tripled the performance of my GLSL shader implementation.
Running a heavy model (+300k vertices) drawn with contours and suggestive contours at 24 fps, average.

The current plan for my thesis is to compare several implementations I made, which all have the same purpose: draw contours and suggestive contours on a given mesh, as fast as possible, as correct as possible. It’s time to review the status of the current builds of these different tools. All of them are written in C++ using OpenGL. Additional libraries are (free)GLUT (for windowing), GLEW (for extension loading) and Trimesh2 (for efficient vertex/mesh operations).
Read more behind the cut.
Continue reading »
A quick and dirty way to render depthmaps. It requires two passes, so it’s not optimal.
I’ll be using this to pass a depthmap texture to a sobel edge detector (in GLSL) in order to draw contours by generating them in image-space. Other renders (normal-mapped, regular diffuse) will be tested too.
Please note that the proper way to do this is to use a FrameBuffer Object to render to, but since compatibility still is an issue (although they’ve been around since 2004), I’m still using the copyTexSubImage()-way. Mea culpa.
Code behind the cut.
Continue reading »