如何实现平滑的切线空间法线? [英] How to achieve smooth tangent space normals?

查看:38
本文介绍了如何实现平滑的切线空间法线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向我的应用程序添加凹凸贴图功能,但我得到了非常多面的模型:

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

发生这种情况的原因是因为我正在计算每个面的切线、副法线和法线,而完全忽略了我从模型文件中获得的法线.

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.

计算目前使用三角形的两条边和纹理空间向量得到切线和副法线,然后通过叉积计算法线.模型加载后,这一切都在 CPU 上完成,然后将值存储为模型几何的一部分.

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?

推荐答案

对于光滑的表面(没有边缘),我是这样做的:

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

  1. 为每个顶点创建空间

double N[3]; //normal
int cnt;

  • 每个顶点初始化

    N={0.0,0.0,0.0}
    cnt=0;
    

  • 计算每个面法线

    normal must be normalized length=1.0 !!! 将此Normal添加到face中使用的所有顶点并增加cnt到所有使用的顶点面对面

    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

    每个顶点归一化

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

    注意 cnt=0 未使用的顶点(除以零)

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

    每个顶点N包含你想要的法线

    per vertex N contains the Normal you want

    现在像现在一样为TBN矩阵(每个顶点)计算T,B向量

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

    输出图像平滑

    我的地球预览(包括大气散射、凹凸贴图等等...)在这里

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

    希望能帮到你

    这篇关于如何实现平滑的切线空间法线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆