Sign in to follow this  

Cosine filtering a cubemap?

This topic is 4592 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I got two questions. 1. Does anyone know of a good/fast way of blurring a cubemap (using the gpu)?, blurring each face doesn't seem like a good solution, since the edges would be very noticeable. 2. How to create a cosine filtered cubemap from a cubemap using the gpu (fast is a +)? Cosine filtered is that each pixel, sums all samples on the hemisphere around that normal using weight = pixelNormal dot sampleNormal. I.e: PixelColor[this] = Sum(max(PixelNormal[this] dot PixelNormal[x], 0) * PixelColor[x]) where this is the current pixel and x is all other pixels (or rather all pixels on the hemisphere seen from this). For question one I could imagine that predefining X number of (random?) samples around the vector [0, 0, 1], then calculate a rotation matrix that rotates [0, 0, 1] to that vector. Then for each pixel in the map you take the normal, rotate it and sample using the precomputed matrices and average them (weighted?). Has anyone tried this? How does it look?

Share this post


Link to post
Share on other sites
You should look at ATI's CubeMapGen:

http://www.ati.com/developer/cubemapgen/

I'm not sure if you really need to blur the cubemap at runtime. I'd suggest blurring into the mip map levels and looking up blurred mip maps at runtime as needed.

I believe the utility also does cosine weighting - again, something you'd want to do as a preprocess.

Share this post


Link to post
Share on other sites
Quote:
Original post by eq
I got two questions.

1. Does anyone know of a good/fast way of blurring a cubemap (using the gpu)?, blurring each face doesn't seem like a good solution, since the edges would be very noticeable.

2. How to create a cosine filtered cubemap from a cubemap using the gpu (fast is a +)?

Cosine filtered is that each pixel, sums all samples on the hemisphere around that normal using weight = pixelNormal dot sampleNormal.
I.e: PixelColor[this] = Sum(max(PixelNormal[this] dot PixelNormal[x], 0) * PixelColor[x]) where this is the current pixel and x is all other pixels (or rather all pixels on the hemisphere seen from this).

For question one I could imagine that predefining X number of (random?) samples around the vector [0, 0, 1], then calculate a rotation matrix that rotates [0, 0, 1] to that vector.
Then for each pixel in the map you take the normal, rotate it and sample using the precomputed matrices and average them (weighted?).
Has anyone tried this? How does it look?


Are you trying to generate a cosign convolved cubemap? If so, the fastest way is probally to take it into SH space and do the convolution in frequency space - then take it back.


Share this post


Link to post
Share on other sites
Quote:
You should look at ATI's CubeMapGen:

The ATI program seems useful, however it only produced black results.
However I'm not in need for an offline tool that do these kind of things (already have CPU-side code that does what I need), rather I'm intereseted in fast GPU methods (approximates or not).

Quote:
SH space and do the convolution in frequency space

This seems promising, I haven't done any SH programming yet and haven't put myself into all of the math so I might be very wrong but could this be accomplished like:

1. Each pixel, for each face in the cube map have a "weight" for the SH coeffs, this can be precomputed and stored in textures.
2. For each face in the cube map, read pixel and SH weights, multiply and store the results in textures (one pass or more depending on the number of coeffs).
3. Mipmap these textures down to a 1x1 texture (auto mipgen?) to get the average value for the 6 faces (or should it be the sum?).
4. Add (avergage?) the 6 faces to get the total SH for the cube map.
5. Render to each of the 6 faces, using the predefined weight and the 1 pixel textures to restore a color.

Hove many components do you need to get decent results for RGB textures?

To get and estimate of the cost (assuming a source cubemap of size 256 and a destination of size 32).
I've heard the number 27 somewhere, if thats enough 9 rgb textures could be needed, writing to 3 of them at once (MRT).
I count 1*3 passes for the face=>SH (R/W: 256x256x6 pixels), this can be done in three DP calls.
Then another 8*3 passes to sum the results together (R: 256x256x6 + 128x128x6 + 64x64x6 + 32x32x6 + 16x16x6 + 8x8x6 + 4x4x6 + 2x2x6, W: 128x128x6 + 64x64x6 + 32x32x6 + 16x16x6 + 8x8x6 + 4x4x6 + 2x2x6 + 1x1x6), three DP calls, ping-ponging on the same textures.
Then summing the 6 values together 1*3 pass (R: 1x1x6, W: 1x1), three DP calls.
Then 3*6 passes to recreate a cube-map, using the original weights and the 1x1 (SH).

To sum it up:
Read: ~9 Mpixels or 36 MB using 32 bit textures.
Write: ~4.5 Mpixels or 18 MB using 32 bit textures.
9 render state changes, 4 shader changes, 15 DP calls.
Could be quite effective, but since I'm surely misunderstanding how to use SH, it's all totally wrong :)




Share this post


Link to post
Share on other sites
Chapter 10 of GPU Gems 2 describes in detail how to use spherical harmonics to compute irradiance cubemaps. If you don't have the book, you can get the sample code from http://download.nvidia.com/developer/GPU_Gems_2/CD/Index.html

Share this post


Link to post
Share on other sites

This topic is 4592 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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