VSM and bilinear filtering shader for ATI Radeon

Started by
42 comments, last by jacko13 14 years, 10 months ago
Hi, I'm trying to implement VSM and I have one problem. My Radeon doesn't support bilinear filtering with floating point textures and I don't know how is the best method for solve them. I found this bilinear shader: http://www.ozone3d.net/tutorials/glsl_texturing_p02.php But on edges I have "lines" artifacts. Second problem is performance of it. Currently I use this bilinear function in blur horizontal and vertical (in each sample, so I use it 7+7 times, I use 7x7 gaussian blur) and I also use this when I get moments from floating point texture in shading shader. How can I optimize it and solve bilinear shader artifacts? Meybe You know better filtering shader for it or better solution for apply it (less than 7+7+1). Thanks,
Advertisement
Can you post a screenshot? It's hard to tell but my first guess would be that it's a texture clamping issue.

Try turning on clamping (to edge should do the trick) and see if that works.
[size="1"]
AFAIC your problem is that:
You're performing no hardware filtering and doing in shader "software" bilinear filtering of variance shadow map.
The main problem is that you don't need this - just turn on linear filtering while creating texture/renderbuffer on hardware (in OpenGL use GL_LINEAR as min and mag texture filter).
Then you won't need to filter offset values to get smooth blur, but you would need just to blur the image - you can do it with separable gaussian blur (which is the best solution).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Quote:Original post by jacko13
My Radeon doesn't support bilinear filtering with floating point textures and I don't know how is the best method for solve them. [...]

That is why he is doing software filtering in the first place, isn't it?


Oh ... i missed that, I appologize ...

Anyway less than 7 + 7 samples is impossible, this is minimum for separable gaussian blur.
Although it is possible to filter VSM with Summed area tables - http://http.developer.nvidia.com/GPUGems3/gpugems3_ch08.html, but I really don't know how this will behave on GPU that is not able to do hardware bilinear filtering on fp textures.

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Quote:Original post by Vilem Otte
Anyway less than 7 + 7 samples is impossible, this is minimum for separable gaussian blur.

There's no minimum size for separable Gaussian filter. A 5+5 works fine, for example. You just have to use more passes if you want an equally blurry result. Even a 3+3 is possible, but will have minimal effect, especially without leveraging hardware filtering on subtexel positions.

Also, keep in mind that a good VSM implementation(*) will profit much more from anti-aliasing of the shadowmap geometry, rather than from excessive blurring. If you blur too much, you'll lose a ton of detail, but you will always keep some flickering if you don't FSAA during the rendering pass. The other way round works much better: good FSAA and not too much blur.

Then again, FSAA'ing an FP render target will not work on hardware that doesn't even support bilinear filtering of FP textures. Maybe one should ask oneself if it makes sense to implement an advanced showing technique, which is clearly targeted at highend cards, on a low end GPU.

[offtopic]
(*) There is no such thing as 'good' VSM at this time. The technique is very interesting, but much more research is needed to really make it practicable. Plain VSM is unusable due to the extreme amounts of light bleeding it generates on overlapping geometry. All the papers that say that bleeding is 'acceptable' and 'easy to hide' lie. Simple as that. You might want to look into ESM (a bit better, but not top either), convolution shadowmaps (much better, but much more performance and memory hungry). Or something really nice, but from a completely different corner of maths, realtime stochastic refinement shadow maps. They have the best quality of all, but they're not easy to implement. To be entirely honest, you can get much better results (in terms of quality) by using traditional shadowmapping over a PSSM with 5 or 6 sections and 2k maps, than with any of the currently existing filterable solutions (except for convolution maps).
[/offtopic]
Quote:Original post by Yann L
[offtopic]
(*) There is no such thing as 'good' VSM at this time. The technique is very interesting, but much more research is needed to really make it practicable. Plain VSM is unusable due to the extreme amounts of light bleeding it generates on overlapping geometry. All the papers that say that bleeding is 'acceptable' and 'easy to hide' lie. Simple as that. You might want to look into ESM (a bit better, but not top either), convolution shadowmaps (much better, but much more performance and memory hungry). Or something really nice, but from a completely different corner of maths, realtime stochastic refinement shadow maps. They have the best quality of all, but they're not easy to implement. To be entirely honest, you can get much better results (in terms of quality) by using traditional shadowmapping over a PSSM with 5 or 6 sections and 2k maps, than with any of the currently existing filterable solutions (except for convolution maps).
[/offtopic]

That are some interesting thoughts about VSM. Here is my experience:
It is a really good idea to use EVSM (using exp(c * depth)) if you are going to use VSM. It is very easy to change your working VSM implementation and the lightbleeding is noticeably better without a big performance hit. Unfortunately the lightbleeding is still there, which might be a problem depending on your scene. Personally I am still sticking with VSMs for now, mainly because shadow-acne annoys me even more than lightbleeding in my scene. I have to admit though, that I spent more time tweaking my VSM than trying to minimize shadow-acne, which might be a mistake.
Blurring is not so bad. I sample the moments 5 times and use the average directly before I calculate the shadow-occlusion (no separate blurring). That is a definite visual improvement and considerably faster/ than FSAA on my system. It takes less memory, too. How do you solve the flickering problem with "standard" shadow mapping?

Are there any code samples for ESM around? I can't really find anything.

EDIT: I hope you don't mind me hijacking the thread.
You can find code for ESM here:

]http://pixelstoomany.wordpress.com/2008/06/12/a-conceptually-simpler-way-to-derive-exponential-shadow-maps-sample-code/

It's slightly modified version but you can easily change it back to original form.
Quote:
(*) There is no such thing as 'good' VSM at this time. The technique is very interesting, but much more research is needed to really make it practicable. Plain VSM is unusable due to the extreme amounts of light bleeding it generates on overlapping geometry. All the papers that say that bleeding is 'acceptable' and 'easy to hide' lie. Simple as that. You might want to look into ESM (a bit better, but not top either), convolution shadowmaps (much better, but much more performance and memory hungry). Or something really nice, but from a completely different corner of maths, realtime stochastic refinement shadow maps.

Definitely look at exponential variance shadow maps. They have few if any problems with light bleeding and 32-bit float textures. I agree that light bleeding in typical VSMs is a showstopped in a lot of cases, although it's untrue to say that they're "unusable" as there's a growing number of games that have happily shipped using even stock VSMs.

I'm also surprised that you suggest convolution shadow maps as an alternative... they have terrible problems with light bleeding near *all* occluders, not just second-occluders. They do a good job for stuff like foliage or other probabilistic stuff that you don't really want a precise shadow for, but as a general shadowing solution for non-trivial scenes, I'd even go as far to say that they are borderline unusable. Even layered VSMs - which are more theoretically interesting than anything - almost univerally outperfom them, and exponential VSMs do better pretty much everywhere at a much lower cost.

Do you happen to have a link to 'realtime stochastic refinement shadow maps' by the way? I'd be interested in reading about that.

Quote:Original post by B_old
It is a really good idea to use EVSM (using exp(c * depth)) if you are going to use VSM. It is very easy to change your working VSM implementation and the lightbleeding is noticeably better without a big performance hit. Unfortunately the lightbleeding is still there, which might be a problem depending on your scene.

I'm surprised you're still getting much/any light bleeding with EVSM. In particular if you're choosing a depth range that fairly tightly bounds your camera frustum (or the specific cascade with CSM/PSSM, even better!) and using a c value of ~42 or similar, you should be getting very little, if any light bleeding (i.e. even clamping off 5% of the function should get rid of anything remaining). Note that you can definitely just bound the camera frustum and clamp objects offscreen to 0/1 - there's no point wasting depth precision on objects offscreen as all you need to know is that they're there, not how they compare to one another :)

In case you think I'm making this up, here's some examples of a scene that has crazy-bad light bleeding with stock VSM (and CSM, and some with ESM), but using EVSM and simple depth range clamping to the frusum (which you should always be doing regardless of the shadow technique), there's absolutely no visible light bleeding, even without any "light bleeding reduction" or visibility function clamping:

#1) EVSM, CSM, ESM

#2) CSM

#3) EVSM, CSM

Also note that 'filtering' and 'resolution management' of shadows are orthogonal topics. High quality shadows implementations make good use of both. VSM/ESM/EVSM/etc. work really well together with cascaded shadow maps. Furthermore the ability to use MSAA when rendering filterable shadow maps and anisotropic filtering when looking up into them means that you often get much higher quality for a cheaper cost than the equivalent resolution/# of "standard" cascaded shadow maps.

Back to the original question though, why are you trying to emulate bilinear filtering during the blurring pass? That pass shouldn't need bilinear filtering at all, and should be quite fast (Aside: if it's supported, you can of course use it to lower the number of taps you need to take when blurring, but that's not necessary). The only place you may need to emulate it is in the lookup shader, where there's only a single lookup. That said, if your hardware can't do anisotropic/mipmapped lookups into your shadow map you're losing a lot of the benefit of VSM et al. anyways... as Yann mentions, there's not a lot of point implementing these advanced shadowing techniques unless you're targetting GPUs with at the very least 16-bit filtering/MSAA support, and ideally 32-bit.

[Edited by - AndyTX on June 11, 2009 8:40:13 PM]
Quote:Original post by AndyTX
Definitely look at exponential variance shadow maps. They have few if any problems with light bleeding and 32-bit float textures. I agree that light bleeding in typical VSMs is a showstopped in a lot of cases, although it's untrue to say that they're "unusable" as there's a growing number of games that have happily shipped using even stock VSMs.

I should have mentioned that I already tried EVSM (the modifications to VSM are trivial). It depends on how you defined 'usable'. In my case, the scene is a large exterior urban environment, with the primary lightsource being the sun. As such, the depth complexity is very high, and the depth layer distribution matches quite precisely the worst case scenario for VSM. EVSM are certainly better, but the light bleeding is still noticeable to a degree making the results ugly (semi transparent shadows, visible 'layers' in overlapping shadows especially when the sun is moving, etc). I invested quite some time trying to tweak parameters, but couldn't really find anything that would get rid of the objectionable artifacts.

About games using it, well, have you seen the shadows in GTA4 ? They are horrific, and while not VSM (they're actually much worse than even a naive stock VSM implementation), it shows that production use of a certain technology doesn't necessarily mean said technology is really mature yet.

Quote:Original post by AndyTX
I'm also surprised that you suggest convolution shadow maps as an alternative... they have terrible problems with light bleeding near *all* occluders, not just second-occluders.

That's surprising. I have had quite good results with CSM, after some fiddling around. They would show much less artifacts than any of VSM/ESM/EVSM, although I couldn't get entirely rid of ringing effects. From enduser tests, these artifacts were seen as much more acceptable than the light bleeding of the former algorithms. However, they were too heavy an both fillrate and memory footprint, due to the pretty high order I used for the signal reconstruction.

Quote:Original post by AndyTX
and exponential VSMs do better pretty much everywhere at a much lower cost.

I have had almost opposite results. What order did you use on your tests for CSM ?

Quote:Original post by AndyTX
Do you happen to have a link to 'realtime stochastic refinement shadow maps' by the way? I'd be interested in reading about that.

Here you go. That's a very basic paper, but it shows the ideas behind the technique. In a real application, the algorithm needs to be refined a bit (so to get nice soft shadows, better temporal filtering to get rid of remaining temporal noise, Monte-Carlo sampling of the shadow map and support for dynamic objects by partial invalidation of the temporal cache). This algorithm can be combined with PSSM and friends, and optionally with some form of post-perspective correction. The quality of the results far outperform everything I have ever seen with current filterable shadowing algorithms, and the cost is acceptable (assuming a fully deferred shadowing system). The only problem is that you need a more or less high framerate in order for the convergence to be unnoticeable (it gets problematic below 30 fps).

Quote:Original post by B_old
I'm surprised you're still getting much/any light bleeding with EVSM.

It really depends a lot on your scene and its specific depth distribution. As I mentioned earlier, I still experience quite a lot of light bleeding with EVSM, with the light source being the sun. YMMV. I haven't tried (E)VSM on smaller artificial lightsources, which have a quite different depth distribution. Anyone did ?

This topic is closed to new replies.

Advertisement