Simulating lighting using volumetric meshes.

Started by
8 comments, last by hamsham 9 years, 9 months ago

A little while ago, I posted a topic about combining multiple lights into a volumetric texture, then render meshes with the speed of a deferred renderer and the same quality of a forward renderer.

http://www.gamedev.net/topic/652393-hypothesizing-a-new-lighting-method/

Since that experiment flopped [miserably], I'm reworking my lighting implementation but still trying the texture volume. I've so far rewritten my engine to support hardware instancing (to simulate a volume) but the trouble I'm facing is rendering lights to a volume. 3D textures seem to only include 6 faces rather than an area bound by 6 sides. Are there any rendering methods that actually allow for volumetric textures (something that I could try to access in a shader)? The closes thing I could find was rendering 109 2D textures but that's extremely excessive when I have the rest of an entire scene to render:

http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering

What I've done so far is combine a few lighting calculations into a single one. This has so far allowed me to render 34,000,000 vertices at around 47 FPS/0.021 MS but this is only with one light on pretty fast hardware. I imagine that I could draw my lights to a g-buffer and render more but that would cause me to render meshes before the lights (when what I want to do is the opposite; render a light volume, then render meshes).

Long story short: has anyone had success with rendering full volumetric textures at a decent speed?

Advertisement

Sounds a lot like Crytek's Light Propagation Volumes, which never had enough precision for anything more than secondary illumination and increases memory requirements by squared or more as you extend the range of the illumination. Alternatively it also sounds like the same hack used by Bungie in Destiny/Irrational in Bioshock Infinite/Epic currently in UE4. All of them render lighting information to a volume texture which is then used for deferred rendering of transparencies. Trouble there is it's all too low of a resolution to get very good shadow information or good specular.

Here are some of the examples: http://advances.realtimerendering.com/s2013/Tatarchuk-Destiny-SIGGRAPH2013.pdf http://www.crytek.com/download/Light_Propagation_Volumes.pdf

Sounds like you mistake cube maps for 3D textures. Cube maps only have 6 faces, but all relevant rendering APIs have true 3D textures as well. In GL you're looking for GL_TEXTURE_3D and related functions.

Sounds a lot like Crytek's Light Propagation Volumes, which never had enough precision for anything more than secondary illumination and increases memory requirements by squared or more as you extend the range of the illumination. Alternatively it also sounds like the same hack used by Bungie in Destiny/Irrational in Bioshock Infinite/Epic currently in UE4. All of them render lighting information to a volume texture which is then used for deferred rendering of transparencies. Trouble there is it's all too low of a resolution to get very good shadow information or good specular.

Here are some of the examples: http://advances.realtimerendering.com/s2013/Tatarchuk-Destiny-SIGGRAPH2013.pdf http://www.crytek.com/download/Light_Propagation_Volumes.pdf

@Frenetic Pony these are some really interesting thing I can try in order to keep this project going! Global illumination is a little beyond the scope of what I am thinking of trying at the moment but it definitely looks promising. The method described in the Destiny presentation seems closer to what I think I can try though. Thank you!

Sounds like you mistake cube maps for 3D textures. Cube maps only have 6 faces, but all relevant rendering APIs have true 3D textures as well. In GL you're looking for GL_TEXTURE_3D and related functions.

Exactly what I was looking for. I think if I can render my lights to a small 3D texture buffer, then scale it and apply the buffer to my geometry I will be able to render quite a few lights at a relatively small cost.

I'm not sure about OpenGL, but in D3D11 you have to render to a slice of a 3D texture at a time. If you want to fill the 3D texture will data, I would suggest using compute shaders rather than directly rendering...

you can try to improve the situation by using either MRT for rendering multiple slices or by using geometry shader to render triangles into multiple rendertargets.
I'm not entirely sure about how 3D textures work in OpenGl either but if they basically boil down to slices then I may have to move onto another option. Otherwise I was going to do exactly what @Krypt0n said and render light volumes to a MRT with a 3D texture as it's target. Afterwards I can scale the final texture to overlap my scene, getting a decent lighting approximation.

The renderer side is going to treat it as slices. If you really want to go this route, you're probably looking at using a geometry shader to replicate the light volume geometry out to all slices covered by it, doing the appropriate projections and such.

The practicality of all that seems questionable, memory restrictions are going to keep your lighting exceedingly lowres, and you're blowing the vast majority of it on empty or useless space.

How you are planning to store light to that 3d texture? Do it preseve directionality?

The renderer side is going to treat it as slices. If you really want to go this route, you're probably looking at using a geometry shader to replicate the light volume geometry out to all slices covered by it, doing the appropriate projections and such.

The practicality of all that seems questionable, memory restrictions are going to keep your lighting exceedingly lowres, and you're blowing the vast majority of it on empty or useless space.

That's actually the exact method I was planning on using in order to keep the lights within the texture volume. Each light would be rendered at a relative position within the 3d texture, then extend its area of influence to the edges and reduce the light's intensity as the distance from its origin increases. Performance-wise, I think my biggest concern will be texel rate. I'm not sure how big of an impact it will have on performance but it's still worth a shot to at least try. I will likely start out with a 256x256x256 texture volume and scale from there as needed.


How you are planning to store light to that 3d texture? Do it preseve directionality?

No, storing direction was what I thought to do originally but that ended up becoming problematic when lights overlapped each other. I'm just going to store each light's color for now and try to blend them in the pixel shader.

It might take a while to actually implement this in my engine right now though. My job just recently doubled in workload and I started school a few days ago. I'll get a quick experiment up this month hopefully and will post the results as soon as I can.

This topic is closed to new replies.

Advertisement