不使用Tangent/Bitangent向量的法线贴图

Row*_*bel 1 opengl 3d webgl

不幸的是,许多教程将TBN矩阵描述为任何类型的法线贴图的事实必须,而没有详细了解为什么会出现这种情况,这使我对某个特定场景感到困惑

让我们假设我需要在屏幕上的简单四边形上应用凹凸/法线贴图,以后可以通过它的正常矩阵进行变换

如果在任何变换之前"静止位置"中的四边形曲面法线正好指向正z方向(opengl),仅仅用模型矩阵变换从正常纹理贴图中读取的矢量是不够的?

vec3 bumpnormal = texture2D(texture, Coord.xy);
bumpnormal = mat3(model) * bumpnormal;  //assuming no scaling occured
Run Code Online (Sandbox Code Playgroud)

我确实理解如果我们计算立方体上的凹凸正常而不计算具有相同纹理坐标的不同面实际上具有不同方向的情况会如何改变,这引导我进入下一个问题

假设整个模型仅使用单个法线贴图纹理,而不在模型的不同部分重复所述纹理坐标,是否可以保存为每个顶点存储的切线/比特向量的6个浮点数以及TBN的计算矩阵altogheter通过简单地用模型矩阵转换凹凸正常得到相同的结果?如果是这种情况,为什么它不是首选解决方案?

Nic*_*las 6

如果在任何变换之前"静止位置"中的四边形曲面法线正好指向正z方向(opengl),仅仅用模型矩阵变换从正常纹理贴图中读取的矢量是不够的?

没有.

假设你从法线贴图得到的值是(1,0,0).这意味着地图中的法线指向右边.

那么......到底是哪里?或者更重要的是,当我们说"正确"时,我们处于什么空间?

现在,您可能会立即认为模型空间中的权利只是+ X. 但问题是,事实并非如此.为什么?

因为你的纹理坐标.

如果你的模型空间矩阵在模型空间Z轴周围顺时针旋转90度,你用这个矩阵变换你的法线,那么你得到的法线应该从(1,0,0)变为(0, -1,0).这是预期的.

但是如果你有一个面向+ Z的正方形,并且围绕Z轴旋转90度,那么是否应该产生与旋转纹理坐标相同的结果?毕竟,纹理坐标定义了U和V 对于模型空间的意义.

如果正方形的右上角纹理坐标为(1,1),左下角为(0,0),则纹理空间中的"右"表示模型空间中的"右".但是如果你改变了映射,那么(1,1)位于右下角,而(0,0)位于左上角,那么纹理空间中的"右"已经变为"向下"(-Y)模型空间.

如果忽略纹理坐标,从模型空间位置到纹理上的位置的映射,则(1,0,0)法线仍将在模型空间中"正确"指向.但是你的纹理贴图表明它应该在模型空间中指向下(0,-1,0).就像你旋转模型空间本身一样.

对于切线空间法线贴图,纹理中存储的法线与纹理在曲面上的映射方式有关.定义从模型空间到切线空间(纹理映射的空间)的映射是TBN矩阵的用途.

随着对象和法线之间的映射变得更加复杂,这变得更加复杂.您可以为四边形的情况伪造它,但对于一般数字,它需要算法.毕竟,映射不是常量.它涉及拉伸和倾斜,因为不同的三角形使用不同的纹理坐标.

现在,存在对象空间法线贴图,其生成明确在模型空间中的法线.这些避免了对切线空间基矩阵的需要.但它将法线贴图与其使用的对象紧密联系在一起.你甚至不能做基本的纹理坐标动画,更不用说允许法线贴图与两个独立的对象一起使用.如果你正在进行骨质剥皮,它们几乎是不可行的,因为三角形通常会改变尺寸.