Normal and height maps

First: a good year to you all!!!

Back to business…
I have a normal map, and I want to add more detail (normals) to it. The detail is stored in a height map. The way I’m doing this is to transform the height map to a normal map add then add the two of them. Is this correct?! Is there a better way?

At a minimum, you need to re-normalize after adding. That will make it “work” although the result is probably not exactly what you want.

What you REALLY want is probably to start with two height maps, where the second height map is applied to the first height map using some scaling, and in the tangent space of that first height map. You can do this the expensive way by calculating a tangent base per pixel, and using that base to apply the second height map’s normal output.

You can also treat the normals as rotations, and apply the rotation of the second normal to the existing first normal. That’s also very close to what I think you really want.

If you do this real time, then neither of these mechanisms work all that quickly.

I want to do this at startup… I’ll try converting the normal do height, add the two and then create the final normal map.


adding two normal maps together isn’t the solution. if you want to add the detail normal map correctly, you have create Normal,Tangent and Binormal for every pixel of the first texture, and then multiply the vector(pixel) from the 2nd texture with it.
here is my code for it:

unsigned char *mix(TGABUFF *tb,unsigned char *a,unsigned char b)
{ int num = tb->w
unsigned char *d=(unsigned char )malloc(num4);
float A[3],B[3],C[3],M[9],xn[3],yn[3];

for(int t=0;t<num;t++)
{ expand(B,&a[t4]); // convert pixel to float, normalized vector
// create norm,bin,tan
// setup 3x3 matrix
M[0] = xn[0]; M[1] = yn[0]; M[2] = A[0];
M[3] = xn[1]; M[4] = yn[1]; M[5] = A[1];
M[6] = xn[2]; M[7] = yn[2]; M[8] = A[2];

// 3.roatate normal
C[0] = B[0]*M[0] + B[1]*M[1] + B[2]*M[2];
C[1] = B[0]*M[3] + B[1]*M[4] + B[2]*M[5];
C[2] = B[0]*M[6] + B[1]*M[7] + B[2]*M[8];
// convertback to pixel

return d;

(this code is tested with textures generated with the normtool plugin for photoshop from nvidia)