使用现有法线平滑切线。OpenGL照明

使用现有法线平滑切线。OpenGL照明,opengl,math,graphics,Opengl,Math,Graphics,我有一堆网格组成一个地形。没有一个大网眼。它来自一个游戏,我正在为玩家制作一个工具来计划战斗 包含的所有网格都是顶点和平均法线。没有切线 我可以很容易地创建切线和双切线,但是看起来很糟糕。它们需要像往常一样平滑或平均在一起。我需要从小网格创建一个大网格来进行平滑。似乎有很多工作是白费的 我的问题是,因为我已经有了平滑/平均状态的法线,有没有办法用它们来修正切线 我在着色器中使用创建TBN矩阵。它的作品,但在头是昂贵的,因为我画了成千上万的4层,混合纹理,texel 更新 好的。。。据我所知,不能

我有一堆网格组成一个地形。没有一个大网眼。它来自一个游戏,我正在为玩家制作一个工具来计划战斗

包含的所有网格都是顶点和平均法线。没有切线

我可以很容易地创建切线和双切线,但是看起来很糟糕。它们需要像往常一样平滑或平均在一起。我需要从小网格创建一个大网格来进行平滑。似乎有很多工作是白费的

我的问题是,因为我已经有了平滑/平均状态的法线,有没有办法用它们来修正切线

我在着色器中使用创建TBN矩阵。它的作品,但在头是昂贵的,因为我画了成千上万的4层,混合纹理,texel

更新

好的。。。据我所知,不能用普通的。。 昨天我花了一整天的时间编写代码,在巨型网格上创建,然后将其返回到其截面网格。 尼科·施赫特勒:

for(int i = 0; i < getVerts().length; i += 3) {
     Vector3f v0 = getVerts()[i].getVectorXYZ();
     Vector3f v1 = getVerts()[i + 1].getVectorXYZ();
     Vector3f v2 = getVerts()[i + 2].getVectorXYZ();

     Vector2f uv0 = getVerts()[i].getVectorUV();
     Vector2f uv1 = getVerts()[i + 1].getVectorUV();
     Vector2f uv2 = getVerts()[i + 2].getVectorUV();

     Vector3f n = getVerts()[i].getVectorNXYZ();

     Vector3f deltaPos1 = new Vector3f();
     Vector3f.sub(v1, v0, deltaPos1);
     Vector3f deltaPos2 = new Vector3f();
     Vector3f.sub(v2, v0, deltaPos2);

     float deltaUv1 = uv1.getY() - uv0.getY();
     float deltaUv2 = uv2.getY() - uv0.getY();

     // Tangent
     float tx = (deltaPos1.getX() * deltaUv2) - (deltaPos2.getX() * deltaUv1);
     float ty = (deltaPos1.getY() * deltaUv2) - (deltaPos2.getY() * deltaUv1);
     float tz = (deltaPos1.getZ() * deltaUv2) - (deltaPos2.getZ() * deltaUv1);
     Vector3f t = new Vector3f(tx, ty, tz);

     // Bitangent
     Vector3f b = new Vector3f();
     Vector3f.cross(n, t, b);

     // Final tangent
     Vector3f smoothTangent = new Vector3f();
     Vector3f.cross(b, n, smoothTangent);
     smoothTangent.normalise();

                   // These are where I store all the vertex data, so it's one tangent per vertex.
     getVerts()[i].setTXYZ(smoothTangent);
     getVerts()[i + 1].setTXYZ(smoothTangent);
     getVerts()[i + 2].setTXYZ(smoothTangent);
  }
for(int i=0;i
事实证明,有一种方法可以使用法线将切线和双切线与平均/平滑法线对齐

这两条线强制切线和双切线与法线成90度角。 “克-施密特过程”


你能展示一下你用来计算切线的简单方法吗。。它有很多代码。。。这不适合评论,但与大多数方法的效果相同。看看这是否有助于你[链接]这基本上就是我正在做的。你可以编辑你的问题以添加更多信息(这是你应该为代码做的)。似乎只是覆盖顶点可能已经存在的任何切线,而不是覆盖所有入射面上的平均值。此外,您还可以跟踪相邻面片中的相应顶点,并像通常一样将其计入平均值。顶点只包含位置。法线存储在PNG图像中,进行平均,并压缩为仅包含X和Z。PNG的法线已处于平滑状态。我正在处理游戏中的地形块,并在寻找一个简单的解决方案。然而,在思考这个问题时,我最终重建了数据并平均了TBN。我发布了一个答案,据我所知,如果你所有的都是处于平均状态的法线,那么这个答案是有效的。它被称为正交校正或克-施密特过程。
t = normalize(t-dot(n,t)*n);
b = normalize(b-dot(n,b)*n);