Relief and Parallax mapping - Fabio Policarpo's 'att' term with deferred shading

Started by
0 comments, last by melax 16 years, 9 months ago
Has anyone dealt with the implications of using the lighting equation in Policarpo's parallax or relief mapping with deferred shading?? Referring to Fabio Policarpo's pixel shaders for relief and parallax mapping, the lighting equation includes an additional 'att' term that is the dot product with the original surface non-bumped (face) normal. Note that this is not typical light distance attenuation, but rather a kind of incident light to surface normal attenuation. Here's a code snippet from the shader: float att = saturate(dot(Ln,IN.normal)); // use normal from vertex shader float diff = saturate(dot(Ln,tNorm)); // from normal map rotated by tbn float3 finalcolor = AmbiColor*texCol + att*(texCol*DiffColor.xyz*diff+SpecColor*spec); I have looked and not found any recent discussion on this or similar term. I see many articles on bump mapping that dont mention it. So i'll first point out the obvious. This term will prevent a light situated behind the polygon from lighting any pixels on the face. Obviously this is useful for a light that doesn't cast shadow. If a particular light does shadowing (either shadowmap or stencil) then what this term prevents is the "discontinuous" change in lighting that occurs when a light comes up over the horizon of a given triangle. Without it any pixel with normal bent toward the light would suddenly brighten. Years ago, Mark Kilgard identified this very phenomenon and suggested a steep ramp. From some of his old power point slides on the subject: diffuse = min(8*max(0,Lz),1) * max(0,L dot N) The first term is effectively the dot product with the face normal. The reason no dot product is there is that Lz is the light vector in tangent space already. Clearly the multiplication by 8 is the "steep ramp" suggested. In comparison Policarpo's att term would be a very shallow ramp. Note, the shaders in Policarpo's papers and website are the same as the reference shaders on Nvidia's site. "Steep ramp versus shallow ramp" isn't my main question, but I'm curious why this term was chosen this way. Does anyone have any insights? And now for the real question.... Has anyone dealt with this issue (or similar issues) when using deferred shading. i.e. g-buffer (opengl) or multiple render targets (d3d). I've tried a couple variations to the lighting equation in an attempt to remove the dependence on the original surface normal. But sadly they just dont look as good. To properly recreate the same look of Policarpo's shader, I had to also store the the original polygon surface normal in addition to the bumped/rotated normal. So that's now TWO normal vectors, a position, and a diffuse color so far. Note that additional properties like gloss can be stuffed into MRT alpha channels. I like the elegance of deferred shading, it works well if the bulk of the scene is shaded the same way and there are lots of little lights everywhere. Despite talk of doing bump, parallax, or relief mapping, none of the samples or discussions on deferred shading mentioned having to store this extra normal. Is there something obvious that I missed? I was thinking of experimenting further with storing the dot product of the rotated normal and the original face normal: dot(in.normal,in.normal*tbn). Then at lighting time would give me the angle that the normal was preturbed so could limit any lighting to a cone around the stored normal direction. However, I know that this would definitely make the grooves darker than what I'm getting now. Rather than re-inventing the wheel here, I'm curious how other people have approached this problem, or if everybody just ignores it. And then what about trying to do relief mapping with shadows? Has anyone achieved this using deferred shading? Will I run into a "brick wall" trying to render a brick wall this way? Thanks in advance for any comments anyone may have. And thanks for all the lively discussions on deferred shading - most insightful. s melax [Edited by - melax on July 24, 2007 12:46:05 PM]
Advertisement
Ok I did a little further digging. It turns out the same guy posted a deferred shading demo of relief and normal mapping as well. In particular look at the demo under the section "Deferred Shading Relief Mapping" on page http://fabio.policarpo.nom.br/relief/index.htm.

In this case, the lighting equation used does not have a term corresponding to the dot product between the light vector and the other normal (the geometric/triangle one that is just interpolated from the vertex normals). While there is a variable 'att', in this case it is a typical light distance attenuation term. Put simply, they just use the usual MRTs for position, normal and diffuse.

The demo looks good, but, as one might expect, running the demo using the normal mapping technique you do see the bumps becoming lit from a light source behind the polygon. The 'att' term in the other relief map .fx file would have prevented that from happening. 'att' might not have been the best choice for that variable name in this case. This is better described as "geometric self-shadowing". See http://developer.nvidia.com/object/gpu_bump.html . Yes its old, so ignore the low level implementation details and pre-cg speak of the day and just look at the pictures of the torus with and without proper geometric self-shadowing. Many of the newer cg and hlsl demos and articles on bumpmapping that are floating around dont implement or discuss geometric self shadowing. Admittedly, it may not be that important of an issue if all the lights are casting geometric shadow anyways.

For me its not the self shadowing, but just that the parallax shading somehow looks a lot better with this extra term thrown in the lighting equation. It seems to prevent too much light being reflected from the grooves on the surface when being illuminated with a light at a low angle of incidence.

Im sure its possible to tweak the art (light parameters and the diffuse texture) to make things look just as good with a simpler lighting equation. I'd rather keep the number of render targets to a minimum.

This topic is closed to new replies.

Advertisement