繁体   English   中英

用于OpenGL顶点着色器的NormalMatrix?

[英]NormalMatrix for OpenGL vertex shader?

我正在使用Assimp导入3d模型,并为其提供法线贴图的切线和双切线,但是我无法弄清楚用于将顶点着色器中的切线和双切线矢量与之相乘的矩阵是什么? WorldViewProjection矩阵还是其他一些专用的“正常矩阵”?

更新:我的顶点着色器

const std::string gVertexShader =   "#version 330                                                                                       \n \
                                                                                                                \n \
                                        layout(std140) uniform;                                                 \n \
                                                                                                                \n \
                                        uniform UnifTransform                                                   \n \
                                        {                                                                       \n \
                                            mat4 mWVPMatrix;                                                    \n \
                                            mat4 mWorldMatrix;                                                  \n \
                                            float mTextureTilingFactor;                                         \n \
                                        } Transform;                                                            \n \
                                                                                                                \n \
                                        layout(location = 0) in vec3 vert_position;                                             \n \
                                        layout(location = 1) in vec3 vert_normal;                                                   \n \
                                        layout(location = 2) in vec2 vert_texcoord;                                                 \n \
                                        layout(location = 3) in vec3 vert_tangent;                                                 \n \
                                        layout(location = 4) in vec3 vert_bitangent;                                                 \n \
                                                                                                                \n \
                                        out vec3 frag_position;                                                 \n \
                                        out vec3 frag_normal;                                                   \n \
                                        out vec2 frag_texcoord;                                                 \n \
                                        out vec3 frag_tangent;                                                 \n \
                                        out vec3 frag_bitangent;                                                 \n \
                                                                                                                \n \
                                        void main()                                                                                                 \n \
                                        {                                                                                                                   \n \
                                            gl_Position   = Transform.mWVPMatrix * vec4(vert_position, 1.0);    \n \
                                                                                                                \n \
                                            vec4 position = Transform.mWorldMatrix * vec4(vert_position, 1.0);  \n \
                                            vec4 normal   = Transform.mWorldMatrix * vec4(vert_normal, 0.0);    \n \
                                            vec4 tangent = Transform.mWorldMatrix * vec4(vert_tangent, 0.0);   // correct matrix?   \n \
                                            vec4 bitangent = Transform.mWorldMatrix * vec4(vert_bitangent, 0.0);    \n \
                                                                                                                \n \
                                            frag_position = position.xyz;                                       \n \
                                            frag_normal   = normal.xyz;                                         \n \
                                            frag_tangent   = tangent.xyz;                                         \n \
                                            frag_bitangent = bitangent.xyz;                                         \n \
                                            frag_texcoord = Transform.mTextureTilingFactor * vert_texcoord;     \n \

TBN(切线,位切线,法线)矩阵(3x3)通常用于从切线空间到对象空间。 您可以以此乘以法线来变换它们。 请注意,法线本质上是定向的,因此与通常处理的大多数变换矩阵不同,您只需要一个vec3和3x3矩阵即可; 在我看来,这就是使此特定矩阵“特殊”的原因。 根据使用此矩阵的方式,您可以将光矢量转换为切线空间,也可以将法线贴图转换为对象空间。

通常,虽然您不会分别将切线,双切线和法线向量相乘。 它们定义了您的向量空间基础,应该单独使用。 从这三个向量派生用于转换为向量空间和从该向量空间移出的矩阵。


通过执行以下操作(伪代码),您将创建从切线空间转换为对象空间的矩阵:

mat3 (Tangent, Bitangent, Normal);

当然,您可以使用逆函数从对象空间到切线空间。 Assimp可能会生成(大约)正交正交基向量,因此可以保证存在逆,并且在这种情况下可以将其表示为转置。

但是,切线和双切线不能保证正交,因为可能会出现纹理扭曲,而且两个都不一定垂直于法线。 在输出TBN向量时,某些模型导入软件会执行正交化作为后处理步骤,大多数教程似乎都假定这种关系始终存在。

切线和双切线(也称为双法线)遵循与法线相同的规则。 实际上,切线,双法线和法线形成了表面局部空间的基础,可以用3×3矩阵表示。 该空间通过模型视图矩阵(也称为法线矩阵)的逆转置进行转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM