I recently stumbled across several articles about using "partial derivative maps" rather than normal maps - i.e. altering the surface normals using the partial derivatives of the heightmap rather than using the normals directly. This seems really powerful to me, as partial derivatives are a lot easier to work with for things like combining multiple normal maps, correcting stretching/scaling issues, etc. And according to this article, if you use partial derivatives you don't have to store tangent space vectors.

The article talks about "perturbing" the surface normal by the surface gradient and links to a paper by Morten Mikkelsen for details of the math behind it. Unfortunately, the link is broken, and I can't find any other links to the paper online. Could someone explain exactly what is going on with this process, or link to a paper that explains it? Is it "correct" in the sense that on a surface with orthogonal s and t surface vectors (not sure what to call these) it will produce the same result as tangent space normal mapping?

I made an attempt at implementing... something (apparently not this since it didn't end up working and I ended up calculating a form of the tangent space), but I had problems with seams across triangles. My technique goes something like this:

1) Find the s and t "vectors" - the direction in space (screen space in my case) in which s and t are increasing. These will NOT necessarily be orthogonal (if the texture is skewed), but that's okay. The magnitudes of these vectors represents the size the texture is scaled to. So basically, this is reconstructing a non-orthogonal tangent space with the "z" vector being the triangle's face normal. Call these T and B.

2) Orthogonalize T and B with respect to N, but do this separately for each of them. That is:

T' = T - N*(T . N)

B' = B - N*(B . N)

and then scale them back up to their original magnitudes. So now you have a non-orthogonal tangent space, TBN.

3) Apply the derivative map. If D is the vector of partial derivatives from the normal map, then:

Dx' = T' + N*Dx

Dy' = B' + N*Dy

N = normalize( cross( Dx', Dy' ) )

So you treat Dx and Dy as being the partial derivatives in the non-orthogonal tangent space (i.e. the change in N along T' and B') and then take the cross product of Dx' and Dy' to get the normal.

Unfortunately, this technique causes seams across triangles when the T and B vectors "change sharply" (unless it's because I messed up my math). I was hoping that since I was using the "true" tangent space with derivatives (not an orthgonalized one, which technically doesn't produce the true normals if the texture is skewed) this wouldn't be the case, but I guess this technique would still require tangent space "averaging".

What I don't understand is how the normal perturbing method, or ANY method, could possibly work without some form of smoothing/averaging going on across triangles. The article I linked to talks about perturbing by the surface gradient. But if the s and t vectors "sharply" changed across an edge, wouldln't the gradient also sharply change and cause a noticeable edge?