Ambient Occlusion Maps

Filed under:Rendering — posted by Brian on March 27, 2008 @ 1:42 am

Here's a brief summary of various programs I've been trying to use to generate AO maps:

faogen: Costs money. Seems pretty reliable and pretty fast. But, against, costs money.

Blender: Er, wouldn't load the .obj file I tried to throw at it, which started things off in exactly the wrong way. Not sure if there's a way to output AO maps... can't find an option in this interface of theirs.

Melody: Stops responding when you do anything. Stops responding when the screensaver starts. Stops responding when the wind blows. Takes a ridiculously long time. It's an nVidia tool, and I'm running on nVidia hardware, so I can't imagine why it's so fragile.

GPU MeshMapper: Surprisingly good. Free, clean interface, works quickly. Requires that I generate a normal map as well, so I can't get reliable timing information from it, which is a bit of a downer. But very fast and good quality results.

Why is it so hard to find anything good?

GLSL Flow Control

Filed under:GPGPU, Rendering, General — posted by Brian on February 11, 2008 @ 1:00 am

The nVidia GeForce 8 Documentation explicitly says that loops should now support run-time condition testing, which to my mind means that non-const variables should be permissible in the condition test. Either way, I should be able to create an infinite loop and have a statement inside which breaks out of the loop once a counter variable reaches a certain, dynamically calculated number. And barring that, I should be able to create a for-loop that executes some max number of iterations, but also has a statement inside which breaks out once the counter variable reaches a certain number.

Of course, none of the above works on my 8800 GTX. I speculated that there was some loop unrolling going on that might be throwing the system off, but a quick look at the generated assembly (using NVemulate, handy little program that it is) indicated otherwise. The last example I gave above is especially weird: I can create a for-loop that executes a max number of iterations and put a break condition inside, but the number I put in as the max number of iterations matters and is very, very touchy, despite that the underlying assembly doesn't change at all. Sometimes I can use 70 just fine, sometimes I can only go up to 10, which is highly restrictive.

This isn't an app-killer; I've got my system basically working and working well, but for some of my requirements the restrictions might get in my way.

OpenGL Debugging

Filed under:GPGPU, Rendering, General — posted by Brian on February 9, 2008 @ 9:58 pm

Alas, the majority of nVidia's profiling/debugging tools only work with DirectX, so I am either forced to insert code myself or find different tools.

GLIntercept looked promising, but it hasn't been updated in a little over two years. There's no logging of geometry shader info in there, which I could really use. It also appears to be mostly non-interactive, preferring to output results to log files (though it does have some very interesting plugins that allow you to dynamically edit shaders or fly through a scene).

glslDevil is much cooler, though very temperamental. It gives dynamic information, allows stepping through GL calls, allows stepping through shaders (very cool), allows putting watches on shader variables (cooler), can show/save the framebuffer, and do a whole lot more. It also gives geometry shader information. It does, however, crash a lot; it crashes when my research program compiles a shader, which is, uh, unfortunate.

GLSL Lessons Learned

Filed under:GPGPU, Rendering, Procedural Content Generation, General — posted by Brian on February 5, 2008 @ 7:08 pm

So apparently GLSL is very touchy, and instead of giving reasonable error messages or even reporting linking errors, it will choose to simply not work. Sometimes this will be a cryptic failure to link with a meaningless OpenGL error; sometimes the shader will just hang indefinitely. Here are some things I've learned:

Just because you have some varyings and they're used all throughout your code does not mean they're active when you link the shader program. This is problematic when you have to get the location of those varyings so that you can bind them to transform feedback. nVidia is kind enough to provide an extension to force varying variables to be active upon linking. Be sure to use that.

If you attempt to access an invalid array index with a constant, it's a linking error, not a runtime error.

Using variables in loop-terminating conditions is, at best, problematic. If you're very, very lucky, you won't have any problems. What's more likely to happen is that your shader will hang indefinitely. For that scenario, a work-around exists where you use a large (not too large, mind) constant instead of a variable, and then break out of the loop when the loop counter reaches the variable.

It's nice that logs exist, but in my experience, they only report hard syntax errors or blatantly invalid statements (invalid implicit casts, for instance). Subtle nuances like the one above are unreported.

These aren't the only problems, but they're the most prevalent ones currently.

From Grammars to Shaders

Filed under:GPGPU, Rendering, Procedural Content Generation, General — posted by Brian on January 24, 2008 @ 8:43 am

So here's the current problem I'm working on:

There's no good way to send the rules across into the shader dynamically, so I'm nixing that. Instead, I'm writing a translator that takes the rules (as already parsed by Lex/Yacc) and converts them directly into shader code. The rules fit mostly neatly into a series of if-then statements, with little problems when variables or functions are encountered (these problems don't seem heavy, but enough to make the translator a little awkward in places).

After that, it becomes a problem of ping-ponging the generated building components back and forth in such a way that I don't waste time processing components that have already reached terminal status. I thought using multiple transform feedback targets would work - sending the finished components to a different buffer than the unfinished - but there's a limit on the amount of information I can feedback in one shot such that I can't get out all the information needed for this. The nasty alternative seems to be searching through the feedback buffer for terminals and shifting them out, but I can't imagine that being in any way fast. If only fragment shaders allowed a greater number of outputs (since processing any component might result in 10+ other components, a fragment shader won't be able to work here). Fragment shaders are more mature than geometry shaders, and I'm afraid that the geometry shader might not provide a significant speed boost even if I get my current problems worked out.

GPGPU

Filed under:GPGPU, Rendering, Procedural Content Generation — posted by Brian on January 17, 2008 @ 8:47 pm

So here are my current gripes with GPGPU programming:

First, CUDA (a GPGPU library from nVidia) isn't supported under Vista. I'm hesitant to move away from Vista, because if I need to tap into DX10 at some point it won't be feasible on XP. At any rate, CUDA programming seems to be, quite frankly, a little icky.

No static global memory exposed by GLSL! It'd be nice if I could do some computations once, store them in some internal structures, and then use those structures the next time a shader is invoked. But alas, those structures are forced to be local to the current invocation of the shader, meaning any precomputation is thrown out.

No serialization/deserialization of textures. Since any real data has to be sent through a texture, it would be awfully nice if I could fill a texture with my structure data, send it across, and easily reassemble the structures on the other side without a huge speed penalty. Not really possible. Instead, I'm going to have to arrange my texture in such a way that it can act as a structure on its own and pray (oh shall I pray!) that texture reads aren't too slow.

Fragment shaders can only produce one output (barring the existence of multiple render targets, which might allow more). This is by design, I know, but it means that I'm *probably* going to be forced to use geometry shaders, which aren't very mature right now. Hopefully transform feedback isn't horribly slow.

I've read in forums (though I haven't benchmarked this personally) that flow control on the GPU is pretty slow. Let's hope that's false, because my shader is going to rely pretty heavily on it.

So, yea, this ought to be interesting.

Geometry Shader

Filed under:Rendering — posted by Brian on October 4, 2007 @ 8:44 am

Here's a 3D mobius strip, toon shaded, glowing, and generated primarily in the geometry shader. To do the rendering, I pass a series of points to the graphics card, where once each point reaches the geometry shader, it gets transformed into a triangle strip which represents a portion of the mobius strip. For some weird reason, for a large number of triangle strips, visual artifacts start cropping up.

The screenshot really doesn't capture how good it looks during runtime.

I really should add the specular term into my lighting equation. It would make this image look a lot prettier.

Also, regarding my last post: I didn't break time. I just made a rookie mistake.

I Think I Broke Time

Filed under:Rendering — posted by Brian on October 3, 2007 @ 12:25 pm

Alright, this is just weird.

I have a scene that I render. Pretty simple scene. Why it renders at less than 60 FPS is beyond me. But that's neither here nor there.

I also have a glow effect, which I mentioned in my previous post. The glow effect renders the scene to a texture then blurs that texture. Thirty times. Then it renders the original scene to the normal framebuffer and alphablends the blurred texture over the scene to create the glow.

And the program runs faster with the glow than without. Nearly twice as fast.

Allow me to reiterate: Drawing a scene, blurring it 30 times, redrawing it, and alpha blending a screen-sized quad over top performs faster than just drawing the scene.

How? It's not physically possible. Not even a string theorist could rationalize this one.

She Glows

Filed under:Rendering — posted by Brian on October 2, 2007 @ 8:25 am

Images done by doing render-to-texture using OpenGL's framebuffer object, blurring the texture 10 times, and blending the blurred texture over the original scene. Notice how the images emit a soft glow (the glow should look better in an actual scene). The first image uses the simplest directional lighting calculation, whereas the second image uses a step function to simulate cartoon shading. They're both a little fuzzy because of JPEG image compression.

Real-Time Shadows

Filed under:Rendering — posted by Brian on September 13, 2007 @ 10:08 pm

Here are a series of links I've come across while researching various shadowing techniques:

Shadow Mapping:

Stencil Shadow Volumes:

Hybrid:

Perhaps these will be of some help to other people. There's a lot of beginner material in there along with some more advanced techniques.


next page


image: detail of installation by Bronwyn Lace