Here’s a little idea I had today. I haven’t seen this posted anywhere else so I thought I’d note it down.
How to generate a midpoint shadow map in one pass:
- Create a shadowmap render target with two channels, which supports blending (e.g. D3DFMT_G16R16F). No z-buffer is needed here.
- Clear your shadowmap texture to the far clip (in both channels).
- Turn off z-writes and z-tests.
- Set the framebuffer blend mode to ‘MIN’.
- Turn off backface culling.
- Render your model.
The trick is, in the shader, simply check the VFACE semantic and based on the result, either write [r=depth, g=+inf] or [r=+inf, g=depth] out (where +inf is the far-clip value).
There’s probably other ways too to work out if it’s a backfacing triangle instead of VFACE.
To test against this, when you read the shadowmap simply average the R and G channels to obtain the midpoint depth. You can run a pass to do this first if you like, or you can do it as you sample the texture.
Disclaimer: I do not claim that this will stop shadowmaps from making you cry yourself to sleep at night.
twitter:
You can just write out r=depth and g= -depth, then r will be min depth and g will be the max depth (because it will be the most negative).
· May 10, 08:17 AM · #
imccown, that’s not the same thing. That gives you the furthest depth in the scene, not the secondmost depth (which is what you’d want for midpoint shadow maps).
· May 10, 01:36 PM · #
interesting logic, but disables several flavors of nifty depth hardware. similar in spirit: disable BF culling. in GS, send triangle to RT A or B depending on facing.
let me zoom out a bit – there is no honest way to map shadows. tracing rays per pixel is required, but algorithms from ray tracing literature are useless.
· May 12, 02:48 PM · #
Oh yeah, it definitely fixes one problem and opens up a whole set of new ones :-)
I think the main problem with shadow maps is biasing, and wide PCF kernels which make the whole thing much worse.
I think the real solution to this is PCSS, and specifically screen-space PCSS. Do the shadow test only once per pixel, using a very thin filter kernel, and then blur the results out. That way, every shadow test will track the receiving geometry exactly, and needs little bias.
· May 12, 07:56 PM · #
If that means there’s no shadow map data structure, then I agree. The relevant data structure is a bitmask per screen pixel, where the ratio of on bits to off bits determines the degree of shadowing. 32 or 64 bits per pixel should suffice.
· May 13, 11:18 PM · #
It’s so great. Thanks.
I use this method as first pass of creating shadow map.
In second pass, I use simple pixel shader that computes Mid-point depth and write mid-point depth to shadow depth buffer.
After second pass, A shadow projection is same as normal H/W shadow mapping.
· Nov 20, 07:20 PM · #