Normal maps

I have two normal maps and I want to add the two of them. Is this the best way to do that?! The results aren’t very good…

static
void ImgSum(unsigned char *op1, const unsigned char *op2, const int comp, const int larg)
{
int i,meta;
float nX,nY,nZ,len;

if (op1==NULL | | comp<=0 | | larg<=0 | | op1==NULL)
return;

meta=complarg3;
for(i=0; i<meta; i+=3)
{
nX=(((float)op1[i+2])/255.0f)*2.0f-1.0f;
nY=(((float)op1[i+1])/255.0f)*2.0f-1.0f;
nZ=(((float)op1[i+0])/255.0f)*2.0f-1.0f;

  nX+=(((float)op2[i+2])/255.0f)*2.0f-1.0f;
  nY+=(((float)op2[i+1])/255.0f)*2.0f-1.0f;
  nZ+=(((float)op2[i+0])/255.0f)*2.0f-1.0f;

  len=(float)sqrt((nX*nX)+(nY*nY)+(nZ*nZ));
  if (len==0.0f)
  	{
  	nX=0.0f;
  	nY=0.0f;
  	nZ=1.0f;
  	}
  else
  	{
  	len=1.0f/len;
  	nX*=len;
  	nY*=len;
  	nZ*=len;
  	}

  op1[i+2]=(unsigned char)((nX+1.0f)/2.0f*255.0f);
  op1[i+1]=(unsigned char)((nY+1.0f)/2.0f*255.0f);
  op1[i+0]=(unsigned char)((nZ+1.0f)/2.0f*255.0f);
  }

}

What exactly are you trying to achieve?
Just adding two vectors or finding the vector
between them(in the plane they create,halfway??) or something else?

Ehh… no. Just adding two NORMAL maps together. Or could I just add them, like: op1[i]+=op2[i]? I find the vector in op1 and op2, add the two, normalize and write the result in the NORMAL map (op1).

[This message has been edited by KRONOS (edited 12-19-2002).]

the normals actually represent the orientation of the plane there… and in fact, they just represent a rotation from the default direction (0,0,1)… so, you could build two quaternions, multiply them, and rotate (0,0,1) through the result… and voilà, your new normal

I just realized that adding them gives the average(hmm, slow on the vector math today).

No you probably want to expand it like you do
otherwise I think you would lose too much precision.

Can you explain what you mean by “The results aren’t very good…”?

Thanks, davepermen, I will try with quaternions…

The results aren’t very good cause the bumps have a faded look. They are there, but almost not. But I’m not certain that this is caused by the sum of the two normal maps. Actually, one thing I’m not 100% sure is how to calculate the tangent and binormal in my model… First, I initialize the tangent and binormal to 0, then for each triangle, calculate them both, add to the 3 vertices of the triangle and normalize in the end (after all of the triangles). Is this accurate?! Maybe the mistake is here…

. First, I initialize the tangent and binormal to 0, then for each triangle, calculate them both, add to the 3 vertices of the triangle[/b]

I’m a bit confused what you mean by “add to the 3 vertices of the triangle”? Do you add ,as in vector add, the binormal and tangent vectors to each vertex?

I’m no expert on ppl but I’ll try to explain
it in a simple way.

After you calculate the lightvectors from each vertex of the triangle(in world-space) to the lightsource you have to
transform the world-space lightvectors into tangent-space.If you know some linear algebra this is a fairly simple basechange.

I found this link, which seems to explain it pretty well. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx11192001.asp

A simple example. Let say you’re drawing a triangle which normal is (0,0,1). In this case your tangent-space and world-space are the same. Your transformation matrix would be the identity matrix.On the other hand, if the triangle normal had been (1,0,0) then the tranformation matrix would be a -90 rotation around the y axis.

What I mean is:

for each vertice
tangent=0
binormal=0

for each triangle
calculate tangent and binormal int tT and bT
for the 3 vertices of this triangle
tangent+=tT
binormal+=bT

for each vertice
tangent.Normalize
binormal.Normalize

Humm, calculating tangent space is fun. There’s 56000 different methods on Internet, and they’re only working with their own conventions. For example, i tried the technic from the link mentionned by roffe a few days ago, and it caused many artifacts where the texture coordinates of my mesh mirror. I’ve finally found one that seems to work, but i’m still not 100% convinced that it will work everytime.

Just to say to be very careful about the tangent space calculation…

Y.

Originally posted by KRONOS:
The results aren’t very good cause the bumps have a faded look

Can’t say I’ve done bump mapping but I would expect that the addition of the two bump maps would give you a “faded” look. Or rather the intensity of the bumps is lessened by the normalisation of the combined values.

I guess that you basically expect one set of bumps to be “added” to the other. This way if you have one map with large bumps (eg. Tiles) and the other with small bumps (eg. Texture of the tile surface) then you probably expect both to be as defined as if you applied one at a time.

This won’t happen though because you are essentially halving the intensity of your bumps through the normalisation process.

I am not sure what the solution would be but I think that you could, perhaps, exagerate the normal maps by applying a sharpen filter after you have combined them? This might improve the output?

OK, many thanks everyone…

[This message has been edited by KRONOS (edited 12-20-2002).]

The problem with normal add and normalizing vectors is that it doesnt really add, it’s more like an average, to really add two vectors in tangent space you have to do something like:

v1.x /= v1.z;
v1.y /= v1.z;
v2.x /= v2.z;
v2.y /= v2.z;
vf.x = v1.x+ v2.x;
vf.y = v1.y+ v2.y;
vf.z = 1;
vf.normalize();

hope it helps.

as u have noticed u cant add them together simply by (n1+n2) / 2.
what u have to do (its been a while since i done it)
for every pixel in the iamge,find out the tangent space orientation matrix of it. use the matrix as the basis to ‘multiple’ the other normal on top of it.

it is quite compilcated to do (but easy to visualize)

This is just a wild guess but: add then normalize .

[This message has been edited by WhatEver (edited 12-26-2002).]