Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
364 views
in Technique[技术] by (71.8m points)

c++ - How to achieve smooth tangent space normals?

I'm trying to add bump mapping functionality to my application but I'm getting very faceted models:

enter image description here

The reason it is happening is because I'm calculating tangent, binormal and normal on per face basis and completely ignoring the normals I'm getting from the model file.

The calculation currently uses two edges of the triangle and texture space vectors to get tangent and binormal, which are then used to calculate normal by cross product. It is all done on the CPU as soon as the model loads and the values are then stored as a part of model's geometry.

    vector1 = vertex2.coords - vertex1.coords;      
    vector2 = vertex3.coords - vertex1.coords;

    tuVector = vertex2.texcoords - vertex1.texcoords;
    tvVector = vertex3.texcoords - vertex1.texcoords;

    float den = 1.0f / (tuVector.x * tvVector.y - tuVector.y * tvVector.x);

    tangent.x = (tvVector.y * vector1.x - tvVector.x * vector2.x) * den;
    tangent.y = (tvVector.y * vector1.y - tvVector.x * vector2.y) * den;
    tangent.z = (tvVector.y * vector1.z - tvVector.x * vector2.z) * den;

    binormal.x = (tuVector.x * vector2.x - tuVector.y * vector1.x) * den;
    binormal.y = (tuVector.x * vector2.y - tuVector.y * vector1.y) * den;
    binormal.z = (tuVector.x * vector2.z - tuVector.y * vector1.z) * den;

    D3DXVec3Normalize(&tangent, &tangent);
    D3DXVec3Normalize(&binormal, &binormal);

    D3DXVec3Cross(&normal, &tangent, &binormal);    
    D3DXVec3Normalize(&normal, &normal);

Is there a way to either calculate these values on per vertex basis, perhaps using the normal supplied with the model or to smooth them out somehow so the model doesn't appear faceted?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For smooth surfaces (no edges) I do it like this:

  1. create space for per vertex

    double N[3]; //normal
    int cnt;
    
  2. per vertex init

    N={0.0,0.0,0.0}
    cnt=0;
    
  3. compute per face normal

    normal must be normalized length=1.0 !!! add this Normal to all vertexes used in face and increment cnt to all vertexes used in face

  4. per vertex normalize

    N/=cnt; // N = average normal from all vertex - neighbour faces
    

    be aware of cnt=0 for unused vertexes (division by zero)

  5. per vertex N contains the Normal you want

    now compute T,B vectors for TBN matrix (per vertex) as you do now

  6. output image is smooth

    My earth preview (with atmospheric scattering, bump mapping and more...) is here

hope it helps


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...