Sign in to follow this  
BlueSpud

Point Light Shadows in Shadow Atlas

Recommended Posts

Hey,

So right now I have a shadow map atlas where I render all of my shadows, similar to how DOOM does it (according to this article http://www.adriancourreges.com/blog/2016/09/09/doom-2016-graphics-study/). This works really well for directional and spot lights, but I'm not sure how I want to proceed concerning point lights. I want to store point light shadows in the atlas, but I'm not sure how the best way to do that is. Is the best way to do this going to be to write an algorithm in the shader to figure out which side to sample from based on the light vector and then just do the calculation as if I were using a cube map, or is there a better solution to this.

 

Thanks

Share this post


Link to post
Share on other sites

It's not that much math to do fake cubemap lookups yourself (on modern AMD GPU's, there's actually no dedicated cubemapping hardware -- a cubemap sampling call in your shader actually gets compiled into a shitload of shader math!!!).

The downside is that you won't get any filtering across face edges, unless you do a whole bunch more maths and 2/3 texture samples.

 

You could also try using spheremaps or paraboloid maps, which lets you use one or two "faces" instead of six.

Share this post


Link to post
Share on other sites

Depending on what version of OpenGL you're targeting you could use cubemap array textures for this. This is core in OpenGL 4.0 and in Vulkan it is always present.

OpenGL: https://www.opengl.org/registry/specs/ARB/texture_cube_map_array.txt and Vulkan: https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkImageViewType.html

 

This would still be different than storing it in your light atlas, but atleast you'd have filtering back.

Share this post


Link to post
Share on other sites

It's not that much math to do fake cubemap lookups yourself (on modern AMD GPU's, there's actually no dedicated cubemapping hardware -- a cubemap sampling call in your shader actually gets compiled into a shitload of shader math!!!).

The downside is that you won't get any filtering across face edges, unless you do a whole bunch more maths and 2/3 texture samples.

 

You could also try using spheremaps or paraboloid maps, which lets you use one or two "faces" instead of six.

 

It's not that much math to do fake cubemap lookups yourself (on modern AMD GPU's, there's actually no dedicated cubemapping hardware -- a cubemap sampling call in your shader actually gets compiled into a shitload of shader math!!!).

The downside is that you won't get any filtering across face edges, unless you do a whole bunch more maths and 2/3 texture samples.

 

You could also try using spheremaps or paraboloid maps, which lets you use one or two "faces" instead of six.

Wouldn't I still have issues with sampling and still have to write some custom sampling code with spherical coordinates? To me that seems a bit more complicated than just writing a custom cube map sampler. 

 

Depending on what version of OpenGL you're targeting you could use cubemap array textures for this. This is core in OpenGL 4.0 and in Vulkan it is always present.

OpenGL: https://www.opengl.org/registry/specs/ARB/texture_cube_map_array.txt and Vulkan: https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkImageViewType.html

 

This would still be different than storing it in your light atlas, but atleast you'd have filtering back.

That would work, but then I wouldn't be able to have directional and spot light shadows in the atlas.

Share this post


Link to post
Share on other sites

Wouldn't I still have issues with sampling and still have to write some custom sampling code with spherical coordinates? To me that seems a bit more complicated than just writing a custom cube map sampler.

Yeah, but you only need one or two 2D rects instead of six, and only a single texture fetch if you're ok with seams (circular seam with DP, and singularity/point seam with spherical)  or two texture fetches to fix the seams. Could potentially be a lot cheaper than a custom cube-map, which requires six 2D rects and three texture fetches to solve the seams.
e.g. check out this technique of dual-spheremaps:

https://www.youtube.com/watch?v=WnNOMTDmYTg
 

That would work, but then I wouldn't be able to have directional and spot light shadows in the atlas.

You could always have two atlases - one for directional/spot, and one for omni/point lights. You could also store them both in the one atlas resource, with two views -- one that views it as a 2D texture array, and one that views it as a cubemap array.
 
You could also implement omni/point lights as simply being six spot lights with a 90º angle and a square gobo mask :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this