Since I wrote this post I've written a new technical paper called "Surface Gradient Based Bump Mapping Framework" which does a better and more complete job describing the following.
All my papers can be found at https://mmikkelsen3d.blogspot.com/p/3d-graphics-papers.html
For those interested in the paper Bump Mapping Unparametrized Surfaces on the GPU
which discusses an alternative method to normal mapping. I thought I'd comment on a few additional variants/use-cases.
For instance listing 2 computes the screen-space derivative of the height value. This can also be achieved using precomputed derivative maps. These texture space derivatives can be transformed to screen-space using the chain rule.
// set bFlipVertDeriv to true when texST has flipped t coordinate
int2 dim; dbmap.GetDimensions(dim.x, dim.y);
const float2 dBdUV = dim*(2*dbmap.Sample(sampler, In.texST).xy-1);
// chain rule
const float2 TexDx = ddx(In.texST);
const float2 TexDy = ddy(In.texST);
const float fS = bFlipVertDeriv ? -1 : 1; // resolved compile time
float dBs = dBdUV.x * TexDx.x + fS*dBdUV.y * TexDx.y;
float dBt = dBdUV.x * TexDy.x + fS*dBdUV.y * TexDy.y;
A demo incl. source is available for download and a method for achieving parallax occ./POM mapping, without tangent space, is described in this post.
The advantage to using derivative maps is a better looking visual during texture magnification especially.
The downside is of course using two channels instead of one. Advantages to either method over conventional normal mapping is of course no precomputed tangent space is needed. There are no tangent space splits in the visible region and the method works whether the surface is tessellated or just a standard triangular model.
I also want to point out that one of the significant observations made in the paper is that the underlying parametrization is irrelevant. What determines Blinn's perturbed normal is the distribution of heights and the shape of the surface. Not how the distribution of heights or the surface are parametrized. This can also be exploited in a domain shader to calculate the new normal when displacement mapping.
To do this the derivative is, again, sampled from a precomputed derivative map. It is then transformed to the corresponding domain space derivative using the chain rule. Finally, the domain space derivatives are used as dBs and dBt in listing 1 where vSigmaS and vSigmaT are replaced with the domain space surface derivatives.