PDA

View Full Version : Normal and height maps



KRONOS
01-08-2003, 06:31 AM
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?

jwatte
01-08-2003, 08:00 AM
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.

KRONOS
01-08-2003, 11:12 AM
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.

Thankx

AdrianD
01-14-2003, 05:32 AM
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*tb->h;
unsigned char *d=(unsigned char *)malloc(num*4);
float A[3],B[3],C[3],M[9],xn[3],yn[3];

for(int t=0;t<num;t++)
{ expand(B,&amp;a[t*4]); // convert pixel to float, normalized vector
expand(A,&amp;b[t*4]);
// create norm,bin,tan
set(C,0,1,0);
cross(xn,C,A);
cross(yn,A,xn);
norm(xn);
norm(yn);
// 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
compact(&amp;d[t*4],C,shd*1.25f);
}
return d;
}



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