uv 边界处的法线贴图接缝
Normal map seams at uv borders
当我在我的应用程序中使用法线贴图时,我得到了这样的接缝
enter image description here
我认为切线有问题
我用 Rastertek.com
这个函数计算它们
vector1[0] = vertex2.x - vertex1.x;
vector1[1] = vertex2.y - vertex1.y;
vector1[2] = vertex2.z - vertex1.z;
vector2[0] = vertex3.x - vertex1.x;
vector2[1] = vertex3.y - vertex1.y;
vector2[2] = vertex3.z - vertex1.z;
tuVector[0] = vertex2.tu - vertex1.tu;
tvVector[0] = vertex2.tv - vertex1.tv;
tuVector[1] = vertex3.tu - vertex1.tu;
tvVector[1] = vertex3.tv - vertex1.tv;
den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]);
tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den;
tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den;
tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den;
binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den;
binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den;
binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den;
我使用顶点法线但是当我使用面法线时没有区别我得到相同的图片
我该如何解决这个问题
这是在漫反射纹理中渲染的法线贴图图片
enter image description here
仔细观察渲染后的输出,右上角的光线看起来像是反向的。在左下角,表面上似乎有小树林,在右上角,它们似乎指向外。这可能表明方向有问题。
实际上,查看以漫反射纹理渲染的法线贴图,您有相同的边界。在继续之前确保 "normal map rendered in diffuse texture" 看起来是无缝的。
球体很棘手,因为您无法在整个球体上定义非消失矢量场。 (Hairy ball theorem) 这意味着你不能在整个球体上一致地定义切线和副法线向量,必须有一些跳跃。这对你来说可能不是什么大问题,因为法线贴图是由单独的部分组成的。可以改变每个片段的向量 tu
和 tv
的意义。因此,对于某些片段,一个或另一个被颠倒了 tu'=-tu
、tv'=-tv
,或者两者的顺序可能被颠倒了。 tu'=tv, tv'=-tu
。您将需要某种代码方式来了解哪个补丁需要哪个转换。
解决该问题的一种极端方法是从对象中删除顶部和底部。这将允许您将对象视为一个扭曲的圆柱体,它可以对两个向量具有一致的定义。
也许更好的解决方案是将法线贴图存储为三分量,直接在每个点给出 3D 法线。
假设我们不必担心 90º 以外的旋转,我们可以得到正方形的对称性
- 没有变化 tu'=tu, tv'=tv
- 在 tu=0 中的反射 tu'=-tu, tv'=tv
- tv=0 中的反射 tu'=tu, tv'=-tv
- 旋转 90º tu'=-tv, tv'=tu
- 旋转-90º tu'=tv, tv'=-tu
- 旋转 180º tu=-tu, tv'=-tv
- 反映在 tu=tv, tu'=tv, tv'=tu
- 反映在 tu=-tv, tu'=-tv, tv'=-tu
当我在我的应用程序中使用法线贴图时,我得到了这样的接缝 enter image description here
我认为切线有问题 我用 Rastertek.com
这个函数计算它们vector1[0] = vertex2.x - vertex1.x;
vector1[1] = vertex2.y - vertex1.y;
vector1[2] = vertex2.z - vertex1.z;
vector2[0] = vertex3.x - vertex1.x;
vector2[1] = vertex3.y - vertex1.y;
vector2[2] = vertex3.z - vertex1.z;
tuVector[0] = vertex2.tu - vertex1.tu;
tvVector[0] = vertex2.tv - vertex1.tv;
tuVector[1] = vertex3.tu - vertex1.tu;
tvVector[1] = vertex3.tv - vertex1.tv;
den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]);
tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den;
tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den;
tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den;
binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den;
binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den;
binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den;
我使用顶点法线但是当我使用面法线时没有区别我得到相同的图片
我该如何解决这个问题
这是在漫反射纹理中渲染的法线贴图图片 enter image description here
仔细观察渲染后的输出,右上角的光线看起来像是反向的。在左下角,表面上似乎有小树林,在右上角,它们似乎指向外。这可能表明方向有问题。
实际上,查看以漫反射纹理渲染的法线贴图,您有相同的边界。在继续之前确保 "normal map rendered in diffuse texture" 看起来是无缝的。
球体很棘手,因为您无法在整个球体上定义非消失矢量场。 (Hairy ball theorem) 这意味着你不能在整个球体上一致地定义切线和副法线向量,必须有一些跳跃。这对你来说可能不是什么大问题,因为法线贴图是由单独的部分组成的。可以改变每个片段的向量 tu
和 tv
的意义。因此,对于某些片段,一个或另一个被颠倒了 tu'=-tu
、tv'=-tv
,或者两者的顺序可能被颠倒了。 tu'=tv, tv'=-tu
。您将需要某种代码方式来了解哪个补丁需要哪个转换。
解决该问题的一种极端方法是从对象中删除顶部和底部。这将允许您将对象视为一个扭曲的圆柱体,它可以对两个向量具有一致的定义。
也许更好的解决方案是将法线贴图存储为三分量,直接在每个点给出 3D 法线。
假设我们不必担心 90º 以外的旋转,我们可以得到正方形的对称性
- 没有变化 tu'=tu, tv'=tv
- 在 tu=0 中的反射 tu'=-tu, tv'=tv
- tv=0 中的反射 tu'=tu, tv'=-tv
- 旋转 90º tu'=-tv, tv'=tu
- 旋转-90º tu'=tv, tv'=-tu
- 旋转 180º tu=-tu, tv'=-tv
- 反映在 tu=tv, tu'=tv, tv'=tu
- 反映在 tu=-tv, tu'=-tv, tv'=-tu