07-01-2008, 02:39 PM
As for me 2nd step I simply derive everything I need to know from the the G-buffer. So when I render the light (shading, attenuation, etc) I just add a few more lines and do:
1) Project the shadow map into screen space.
2) Check if fragment is occluded by comparing the view space depth against the value stored in the shadow map.
There is never any redrawing of any geometry or anything like that. All I do is to render the scene to shadow map (from the perspective of the light) using a single "forward rendering" pass, which is something you are doing as well and something that must be done. To cut down on overdraw in this state I make sure to render front to back (so that the z test will discard most fragments) and I also do occlusion culling.
Now for your code.
#1
I assume u mean:
This is just like my first pass and as I said this is the only re-rendering (of scene geometry) I ever do.
#2
Am I correct when I say that you render all geometry intersecting both light and view frustum and then get the distance to light for every affected fragment?
If so then this is pretty much what I do in my light shader code.
#3
Don't you do any light rendering here (shading, attenuation, etc)? Do you just modulate the shadow with the screen or something?
If you do light rendering in this pass then this is exactly like my 2nd step. The only difference is that I incorporate your 2nd step in there too.
Assuming I have gotten all of your stuff right then I am afraid that I cannot see any reason why your method would give any speed ups. If you are using a deferred shader then u can get the view space position (and must do this for attenuation anyway) in the light shader and can use that to calculate if the fragment is occluded (or level of occlusion, if several samples are used).
EDIT: Just saw your second post after writing the above. I think the above covers what that too though.
EDIT2: Text under step 1# made more clear.
1) Project the shadow map into screen space.
2) Check if fragment is occluded by comparing the view space depth against the value stored in the shadow map.
There is never any redrawing of any geometry or anything like that. All I do is to render the scene to shadow map (from the perspective of the light) using a single "forward rendering" pass, which is something you are doing as well and something that must be done. To cut down on overdraw in this state I make sure to render front to back (so that the z test will discard most fragments) and I also do occlusion culling.
Now for your code.
#1
I assume u mean:
Code:
out.depth = in.position.z / in.position.w;
#2
Am I correct when I say that you render all geometry intersecting both light and view frustum and then get the distance to light for every affected fragment?
If so then this is pretty much what I do in my light shader code.
#3
Don't you do any light rendering here (shading, attenuation, etc)? Do you just modulate the shadow with the screen or something?
If you do light rendering in this pass then this is exactly like my 2nd step. The only difference is that I incorporate your 2nd step in there too.
Assuming I have gotten all of your stuff right then I am afraid that I cannot see any reason why your method would give any speed ups. If you are using a deferred shader then u can get the view space position (and must do this for attenuation anyway) in the light shader and can use that to calculate if the fragment is occluded (or level of occlusion, if several samples are used).
EDIT: Just saw your second post after writing the above. I think the above covers what that too though.
EDIT2: Text under step 1# made more clear.