I'm sick. Not only sick of this sore throat I have, but also sick of these light blobs!
But I should probably introduce my program first before I talk about that. I've been developing a program called Voxelcraft for the Starhunter Engine. Voxelcraft creates worlds in cubes, which is simple enough for what I have in mind. The game I would make with it would be reminiscent of old-school games. I'll still be using many different present-time effects such as shadowing, high-dynamic range, depth blur, and such. It's being built with Microsoft XNA.
Previously, I had a deferred renderer working beautifully on my program. Deferred rendering works by seperating the colors, normals, depth, and any other information into different render targets. Combined, this would make up the G-Buffer (the G is for geometry!) I would use the normal and depth buffers to make a buffer that contains all lighting information. Then I would lay that on top of the color buffer, and call that the final render. There were some disadvantages, notably memory bandwidth, but the main advantage of this was that it is perfect for many small lights, because for normal rendering, your number of draws was (number of objects) * (number of lights). With deferred rendering, it's (buffer creation + number of lights). I liked it, until the part where I had to add in the sky.
My game rendered like:
Render G-Buffer-----\
| Color/Specular |------------------------\
| Normal/SpecPower |----->Light buffer-------> Final Scene
| Depth |----/
\-------------------/
I would render the sky as a cylinder. Then I would add that into the color buffer of my G-Buffer during the initialization of it, and then render everything else in. Whenever I moved close to any light, a random blob of light would move across the sky! This is coming from the light buffer. I never had this problem before I put in the sky. I think it had to do with how I was calculating the specular for everything. So I messed around in the lighting effect, and got nothing out of it.
There is a way to draw the sky much later by using the stencil buffer from the G-Buffer draw call. But this is very hard to do in XNA, because XNA clears its stencil buffer every time the render target has been switched! I hear I can fix this by having the render target "preserve contents", but that can't work on XBox 360, apparently. And with the new XNA 4.0, I'm even more screwed because the DepthStencilBuffer has been removed completely, and has been incorporated into RenderTarget2D instead!
So stenciling in the sky is not an option. But I've been looking into a method of lighting called "pre-pass lighting". (http://www.bungie.net/images/Inside/publications/siggraph/Engel/LightPrePass.ppt) It's basically like deferred rendering, but without the color buffer (which has been giving me problems). And since there's no color buffer, the process won't take up as much memory bandwidth for the GPU. I'd still render light into its own buffer, but I would apply it by re rendering the geometry instead. This way, it knows where it should use the light buffer. This gets rid of my "random light blob" problem because it's only been happening in the sky where there's no geometry being rendered.
So now this is my rendering:
----Render sky (without light buffer)-----\
|
Render-------------\ |
| Normal/Specular |------> Light Buffer |
| Depth |-----/ | |
\------------------/ |--------/
V
Re-render scene
geometry w/
Light Buffer
Now everything is working, and the random light blob doesn't appear! But I looked into the light buffer afterwards, and saw that the light blob doesn't appear at all, and I thought that it would anyways. Hmm, must have been something with the color buffer, because I was using that in the original light buffer creation to refer to specular. Oh well, either way, the problem's fixed, and I've implemented a lighting procedure that will (hopefully) run faster!
Creating the sky itself was easy. All it is is a cylinder with a texture of 2:1 ratio, and a bottom and top texture. I read about it on http://blogs.msdn.com/b/shawnhar/archive/2008/11/11/the-sky-s-the-limit.aspx. It works for me, because since I'm using sprites for all characters anyways. (and it's incredibly awkward to display a sprite from above anyways, it'll appear as flat). I rendered the geometry in code using Cos() and Sin() functions, instead of having a cylinder model. I'm pleased with it, but the resolution (512 x 256) is too small in the pic above, so I'll probably increase that to (1024 x 512).
Next, I'll work on sun and moon placement, and water. I want to work on high dynamic range (HDR) at some point, though.



No comments:
Post a Comment