Sign in to follow this  
Batzer

Filtering Cubemaps

Recommended Posts

Hey guys,

 

I'm currently trying to implement Variance Shadow Maps and I just can't figure out how to filter the cubemaps for the omnidirectional lights. For the spotlights I just apply a gaussian blur, but I can' find a way to do this with cubemaps. How do other games tend to solve this problem?

Share this post


Link to post
Share on other sites

Thank you for your answer!

But wouldn't this approche have potential artifacts at the edges of each face? I mean when a shadow is spread across two faces, shouldn't the blur take some texels from both faces?

Edited by Batzer

Share this post


Link to post
Share on other sites

Yes, you will potentially get artifacts along the seams of the cube map if you blur them the way cgrant suggests. I think a lot of games solve this problem by just not having shadowmap support for point lights (or if they do, they might use dual paraboloid mapping or something to minimize both the number of seams that have to be hidden and the memory footprint of the shadowmap).

 

If you really want to use cube maps and filter them correctly you'll have to filter one face at a time, and for each texel you will have to reconstruct the normal that corresponds to that texel, then perform the gaussian blur by sampling the cubemap in the neighborhood around that normal on the unit sphere.

Edited by Samith

Share this post


Link to post
Share on other sites

I think a lot of games solve this problem by just not having shadowmap support for point lights

They use a single 2D texture with all 6 faces on it.


I just can't figure out how to filter the cubemaps for the omnidirectional lights.

Filtering a cubemap texture is extremely slow.
The solution is not to use cubemaps at all. Use a single 2D texture.
If you want a cubemap resolution of 512-by-512, make a 2D texture 512-by-3,072.
The [0,0] - [512,512] area is the left face.
The [0,512] - [512,1024] area is the front face.
Etc.
You render each face of the “cube” into one 512-by-512 section of the 2D texture.

Next you perform filtering. This is fairly basic. You simply have to make a coordinate converter so that taps off the edge of one face go to the proper part of the texture where the correct face is stored.
With that function, filtering is done the standard way.

Rendering with that texture is also fairly basic.
You just have to write your own 3D coordinate converter to take a 3D vector and pick the correct part of the texture to read. This can be made very efficient depending on how you organize the faces of the cube inside the texture.


This is how most game companies do it, and it runs in real-time on devices as low as iPad 3/Xbox 360/PlayStation 3.


L. Spiro

Share this post


Link to post
Share on other sites

On all modern hardware a cubemap is just a texture array with NumSlices = 6, so there's not really much difference (from a hardware POV) between a cubemap and an 'atlased' texture where 6 faces are packed into one long horizontal strip. The main difference is that if you want to you have access to an easy direction->UV conversion in shader, or alternatively if you just want to treat it as an array you can easily address each face using an array index. In D3D11 which behavior you get is dependent on how you set up your shader resource view, and what type is declared in your shader. Personally I would probably go with a cubemap to get the nice cubemap behavior when sampling the filtered shadow map, especially since in D3D11 hardware filtering works correctly across cubemap seams.

Edited by MJP

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