使用具有世界空间法线的切线空间法线贴图

时间:2014-06-15 19:41:56

标签: opengl glsl normals

我在GLSL中处理延迟着色。我在世界空间中拥有所有模型法线,以及位置。整个事情与多边形的世界空间法线完全一样,但我不确定如何添加法线贴图。我知道它建议在观景区做照明,而且我已经尝试过,但是我无法与世界空间相提并论。我现在要解决的是添加法线。我有一个常规的法线贴图,它位于切线空间中。我尝试过以下方法:

  1. 通过法线贴图将世界空间法线乘以似乎没有效果。

  2. 我尝试添加法线贴图的法线,即使我知道它不起作用。

  3. 此时我还不确定还有什么可以尝试的。有没有简单的方法呢?

    Normal-rendering frag shader:

    #ifdef NORMALMAP
    uniform sampler2D m_Normals;
    #endif
    
    varying vec3 normal;
    varying vec2 texCoord;
    
    void main() {
        vec3 normals;
        #ifdef NORMALMAP
            normals = normalize(normal * (texture(m_Normals, texCoord).xyz));
        #else
            normals = normal;
        #endif
        gl_FragColor = vec4(normals, 1.0);
    }
    

    变量"正常"是从顶点着色器传入的世界空间法线。

1 个答案:

答案 0 :(得分:2)

  

我的光线位置都在正常空间。

我不知道"正常空间"这里的意思是诚实的。有#34;普通空间"在数学方面,这是非常不相关的,没有标准的坐标空间,称为“#34;正常空间。”#34;

  

我的问题是如何将切线转换为世界。

你的多边形的世界空间法线不足以解决这个问题(事实上,你需要一个每顶点法线)。要从切线空间转换为对象空间,您需要做三件事:

  1. 您的对象空间法线向量
  2. 表示纹理坐标变化的向量
  3. 表示纹理t坐标变化的向量
  4. 这三个东西一起形成切线空间 - >基础矩阵的对象空间变化(通常称为 TBN ,因为向量称为Tangent,Bitangent和Normal)。

    但是,您不希望在此问题中使用对象空间法线,因此您需要将该矩阵乘以模型矩阵,以便它跳过对象空间并直接进入世界空间。同样,如果您的法向量已经在世界空间中,则需要将其转换回对象空间。在这种情况下,对象空间和世界空间可能是相同的,特别是因为我们在这里只处理3x3矩阵(没有翻译)。但是我从你给出的描述中无法确定。

    最后要注意的是,在这种情况下,您需要传统TBN矩阵的逆。传统上,它用于将矢量 转换为 切线空间,但您希望将它们转换为 out 。旋转矩阵的倒数与其转置相同,所以你真正需要做的就是将这3个向量放在你的行而不是列 1

    1 这假设您的T,B和N向量是直角。这不一定是这种情况,因为它们是从您的纹理坐标派生的。这一切都归结为你用来计算Tangent和Bitangent向量的东西;很多软件会为你重新正交化。