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 矩阵表示。此空间通过模型视图矩阵(也称为法线矩阵)的逆转置进行转换。
相关文章:
- 如何循环打印顶点结构
- D3D11-将混合权重和索引传递到顶点着色器
- 从返回的顶点缓冲区查询顶点结构
- Vulkan 中的动态顶点缓冲区格式设置
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- 如何将一半传递给顶点着色器?
- 在 DirectX 11 中从 GPU 读回顶点缓冲区(并获取顶点)
- QT QOpenGLWidget:如何在不使用数据块复制的情况下修改VBO中的单个顶点值?
- 使用 OpenGL 4.5 更改所选顶点的颜色
- Direct3D 11 - HLSL - 获取顶点索引 ID
- 创建异构顶点数据数组的可移植方法
- 使用 glvertex4i 传递网格面索引时的顶点着色器错误
- 无法从 cso 文件创建顶点着色器(从 fx 文件创建)
- OpenGL 相机移动程序顶点着色器问题
- 使用 std::list 存储顶点并使用 SFML 绘制它们
- 为什么顶点数组对象会导致错误?
- 从 CGAL 3D 网格生成中获取顶点坐标的 -6.27744e+66:mesh_implicit_sphere示例
- 将顶点位置从顶点传递到片段着色器 - 仅在使用 Nsight 进行调试时有效
- FBX SDK 在预期 3 个顶点时返回 4 个顶点
- OpenGL 顶点着色器的 NormalMatrix