Jump to content

Cone Step Tracing


Josh

5,255 views

 Share

Now that we have our voxel light data in a 3D texture we can generate mipmaps and perform cone step tracing. The basic idea is to cast a ray out from each side of each voxel and use a lower-resolution mipmap for each ray step. We start with mipmap 1 at a distance that is 1.5 texels away from the position we are testing, and then double the distance with each steo of the ray. Because we are using linear filtering we don't have to make the sample coordinates line up exactly to a texel center, and it will work fine:

Image3.png.1d18aea77a3082dacb8ceba419d60459.png

Here are the first results when cone step tracing is applied. You can see light bouncing off the floor and reflecting on the ceiling:

1591570195_Engine2018-08-0618-30-23-63.thumb.jpg.2b8cd9a2fea94fd2ebf7b7694714978b.jpg

This dark hallway is lit with indirect lighting:

381244869_Engine2018-08-0618-30-46-19.thumb.jpg.e86fa0efc3bb32f2c80abd2089f89225.jpg

There's lots of work left to do, but we can see here the basic idea works.

  • Like 2
  • Upvote 1
 Share

18 Comments


Recommended Comments

16 minutes ago, Rick said:

I turbo becoming a voxel engine? I'm confused by all the voxel stuff.

It's used for real-time GI calculations. I'm going to take this 3D texture and use it in the regular rendering to lookup the indirect lighting component. The voxels are just so you can see what's going on.

  • Like 1
Link to comment

I am pretty confused about what to do with the texture allocation.

It's best to have six lighting values for each voxel, one for each direction. I suppose you could drop this down to four that are all 129.5 degrees apart, with less accuracy.

We want at least three voxel grids cascading out around the camera.

That means 18 textures, and I am only counting on support for 16 textures, total!

Since we are doing a depth pre-pass, I suppose we could calculate GI in the same pass and write it into a color texture, at the cost of adding a fragment shader (the pre-pass shader doesn't have one right now).

Or we could make a rule that says GI requires 32 textures. Since only 16 is guaranteed that means we definitely need some backup solution for indirect lighting (probably light probes like we use now).

Or we could store just one GI value per voxel, which means the cone step tracing needs to be performed per-pixel in the main pass. Or maybe in a downsampled buffer afterwards.

There are a lot of different ways to do this! Unlike all the academic examples out there, I am required to actually make a good working commercial product that runs fast, so I am pretty much on my own to determine the best approach. Literally no one to date has made a commercial version that includes specular reflections.

Link to comment

If you were to make a rule that GI requires 32 textures, does it drastically change what cards the engine will work on?  I'm not sure how 16 can be guaranteed and not any more.  Is it a memory issue?

Are there other ways to store and manipulate data on the GPU that doesn't use texture slots?  Like Buffer Objects or something...?

Quote

It's best to have six lighting values for each voxel, one for each direction. I suppose you could drop this down to four that are all 129.5 degrees apart, with less accuracy.

Maybe you could bring it down to four to keep it within limits but have the option to use more if the end user wants too use up to 32?  Maybe..

Link to comment

It's a conflict between memory consumption, quality, and speed. This is one of those times when it is nice to have an overarching design goal. In our case, we care about speed, particularly on high-end GPUs at high-frequency displays.

By eliminating the cone step tracing in the final pass and just using six 3D texture lookups, I can make the actual rendering cost of this neglible. It looks bad without six separate directional values. So that really does require 18 256x256x256 RGBA textures(!), equaling 1152 MB. In order to render that you need a full 16 slots of just GI data, so 32 texture slots are required, and you have to cut into the guaranteed texture slots and steal 2.

This gives us texture allocation something like below. You can really only have access to five textures because I need the rest:

  • 0: diffuse
  • 1: normal
  • 2: metalness / specular
  • 3: roughness / gloss
  • 4: emission
  • 5: Skybox
  • 6: BRDF
  • 7: shadow map array
  • 8: cube shadow map array
  • 9: decal texture array
  • 10: GI voxel grid 2 -Z or probe cubemap array fallback
  • 11: GI voxel grid 2 +Z
  • 12: bone data
  • 13: instance IDs
  • 14: Light info
  • 15: Entity matrices
  • 16 GI voxel grid 0 -X
  • 17 GI voxel grid 0 +X
  • 18 GI voxel grid 0 -Y
  • 19 GI voxel grid 0 +Y
  • 20 GI voxel grid 0 -Z
  • 21 GI voxel grid 0 +Z
  • 22 GI voxel grid 1 -X
  • 23 GI voxel grid 1 +X
  • 24 GI voxel grid 1 -Y
  • 25 GI voxel grid 1 +Y
  • 26 GI voxel grid 1 -Z
  • 27 GI voxel grid 1 +Z
  • 28 GI voxel grid 2 -X
  • 29 GI voxel grid 2 +X
  • 30 GI voxel grid 2 -Y
  • 31 GI voxel grid 2 +Y
  • Like 1
Link to comment

That's a lot of textures... but for great graphics at fast speeds it'll probably be worth it.  I'm not familiar with 3D textures but can you store 4 of them in one slot like what can be done with a 2D texture, and then access the appropriate one with UV coords.. or however you access 3D textures?

Link to comment
5 minutes ago, SpiderPig said:

That's a lot of textures... but for great graphics at fast speeds it'll probably be worth it.  I'm not familiar with 3D textures but can you store 4 of them in one slot like what can be done with a 2D texture, and then access the appropriate one with UV coords.. or however you access 3D textures?

You can pack them into an array texture, but they have to be the same size and format. So we are talking about increased complexity of the art pipeline, which I know people would not like.

Link to comment

Yeah I guess people can do that to the 2D textures themselves if they want too, depending on their GLSL skills.  So the 18 256x256x256 RGBA textures for GI can't be packed?  We won't need to access those will we?

Link to comment
7 minutes ago, SpiderPig said:

Yeah I guess people can do that to the 2D textures themselves if they want too, depending on their GLSL skills.  So the 18 256x256x256 RGBA textures for GI can't be packed?  We won't need to access those will we?

How would you pack that? There is no 3D texture array in OpenGL, and the guaranteed max size for 3D textures is 256, so you can't be sure they can be placed in a bigger 3D texture.

Link to comment

Not that I know a ton about this but 256 may be guaranteed but what is the reality for most cards? I have to imagine it's higher.I mean there is the OpenGL spec but then there is the reality of the most popular gfx cards on the market.

 

Did a quick search and was seeing that in OpenGL 3 this size was 1024. What version does LE use again? 4 right? I would think that size would be larger than 256.

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...