Friday, February 19, 2010 at 3:21 AM |  
As we progressed with the building of our second level, we hit one major issue with our rendering solution; lights. Since level 2 is an underwater level, it requires tons of lights to set the mood. Our current rendering method is a forward rendering system. This means for each mesh lit by a light, an additional pass is needed to draw the affected mesh. This becomes a problem as the GPU will be re-rendering meshes for each light.

To solve this problem, most games uses pre-baked light map for this case. However, we opted not to rely on this method as our tool chain is designed for more dynamically build levels (Levels build with prefabs put together). Also, we prefer to have a dynamically lit scene where we can freely move lights around. We believe it actually would save us more time compared to baking lighting which will only slow down the level building.

Having said that, I've decided to tackle this problem the deferred way. However as we know, full deferred renderer has many caveats. They're problematic with different materials and expensive due to sampling of 4 render targets per light. Thankfully, there appears to be a simpler method known as the light pre-pass rendering method, introduced by Wolfgang Engel.

The light pre-pass renderer basically does a lighting pass that accumulate all lighting to a light buffer without the diffuse/albedo part of the scene. The idea is to use less render textures (RT) hence less texture sampling during the lighting stage.

So I began to draft out how I would build my G-Buffer and handle the rendering pipeline.

Bellow is how I plan to layout my G-Buffer:


Note that RT2 is optional and only generated when we want to have full scene motion blur.


Then, to implement the light pre-pass rendering pipeline into our existing shading pipeline, this is what I'm planning to do:



An interesting thing to note is that this method does not incur much extra memory compared to the deferred approach. In fact, the additional memory required for G-Buffer is pretty much already a required memory size when enabling refraction in our current pipeline. Hence, refraction effect pretty much becomes almost free in terms of memory needs.

Obviously this is only just one side of it. On the other side of things, we actually need a light buffer and this is where things start to cost more. For the sake of HDR, we would need to use PF_FLOAT16_RGB or PF_FLOAT16_RGBA. Both format here is actually a 64bbps format which means double the cost of the normal render buffer. For an accurate lighting model, we would need two render target. One for N.L phong lighting, the other for N.H specular lighting. So we would impose extra memory requirement to build a perfect specular lighting model. Annoying. Hence, I'm planning to have an approximate specular mode where we only keep specularity as a luminance value. This way, we only use one light buffer and we leave the specular colour lit base on diffuse light and the material. It shouldn't look too bad I hope.

Aside from that, this new method does introduce a problem. The opaque part of the scene has to be rendered twice. Once for filling the G-Buffer, and second time for the actual material and light composition. This basically means that the initial rendering would not be faster compared to our forward rendering approach. However, it will impose very low cost to having additional dynamic lighting. Personally, I hope this is a correct direction to head for. I do know cards in the range of 8800GTS (which is medium range by now) can handle this no problem. However, lower end cards would suffer, E.G. 9600GTS - which is what I am using for testing. It's already trudging along with all features on at 1024x768 doing 30fps or less which is bad for a racing game.
Posted by Lf3T-Hn4D

4 comments:

Tuan Kuranes said...

About RT2 & motion blur:

- camera blur only saves the whole thing in a racing game imho...
http://www.valvesoftware.com/publications/2008/GDC2008_PostProcessingInTheOrangeBox.pdf
-> if "fast object blur" really needed it could be special case triggered post-process.
(you might be interested on the HDR/tonemapping part too...)

About transparency and deffered :
check the "Rendering Technology at Black Rock Studios" slides at
http://www.bungie.net/News/content.aspx?type=topnews&link=Siggraph_09
and some talk about it there too:
http://whatmakesyouthinkimnot.wordpress.com/2009/08/21/foliage-rendering-in-pure/

February 19, 2010 at 10:38 AM  
Prometheus said...

This is so awesome. I cant wait for it to be implemented. :D Will definitely change the way we light our scenes.

February 19, 2010 at 6:20 PM  
Lf3T-Hn4D said...

Thanks tuan. :) Those were great find. I do know that camera blur will save the whole thing in a racing game. That's one of the reason I'm planning to add it in. (Fake smoothness)

As for transparency and deferred, it seems there's no real technique out there that will be fast enough. All of them deal with quality but they fail to live up to forward rendering performance. The foliage rendering of pure looks interesting. Though, I think we're happy with our alpha rejection based grass. It's much faster and still look pretty good. Besides, with blur and what not, I don't think anybody will bother about the jaggedness of the grass.

February 19, 2010 at 9:19 PM  
sarcastic241 said...

Thanks for this informative post! I really appreciated it :) cafe24 portfolio extension

November 17, 2011 at 6:56 PM  

Post a Comment

Liquid Rock Games and Project Aftershock. All Rights Reserved.