在OpenGL阴影语言(GLSL)中讨论凹凸贴图,镜面高光和此类事物

我有:

  • 顶点数组(例如{0.2,0.5,0.1,0.2,0.4,0.5,...})
  • 法线数组(例如{0.0,0.0,1.0,0.0,1.0,0.0,...})
  • 点光源在世界空间中的位置(例如{0.0,1.0,-5.0})
  • 观看者在世界空间中的位置(例如{0.0,0.0,0.0})(假设观看者位于世界中心)

  • 现在,如何计算每个顶点的Binormal和Tangent?我的意思是,计算Binormal的公式是什么,根据这些信息我必须使用什么?关于切线?

    无论如何,我都会构造TBN矩阵,因此,如果您知道直接基于这些信息构造矩阵的公式,那就太好了!

    哦,是的,如果需要,我也有纹理坐标。
    在我谈论GLSL时,一个逐顶点解决方案将是一个不错的选择,我的意思是,一个解决方案不需要一次访问多个顶点信息。

    ----更新-----

    我找到了这个解决方案:

    vec3切线;
    vec3 binormal;

    vec3 c1 =交叉(a_normal,vec3(0.0,0.0,1.0));
    vec3 c2 =交叉(a_normal,vec3(0.0,1.0,0.0));

    如果(length(c1)> length(c2))
    {
    切线= c1;
    }
    其他
    {
    切线= c2;
    }

    切线=规范化(切线);

    binormal =交叉(v_nglNormal,切线);
    binormal =归一化(binormal);

    但我不知道它是否100%正确。

    最佳答案

    问题的相关输入数据是纹理坐标。切线和法线是局部平行于对象表面的 vector 。对于法线贴图,它们描述的是法线纹理的局部方向。

    因此,您必须计算纹理 vector 指向的方向(在模型空间中)。假设您有一个三角形ABC,其纹理坐标为HKL。这给了我们 vector :

    D = B-A
    E = C-A
    
    F = K-H
    G = L-H
    

    现在我们要用切线空间T,U表示D和E,即
    D = F.s * T + F.t * U
    E = G.s * T + G.t * U
    

    这是一个由6个未知数和6个方程组成的线性方程组,可以写成
    | D.x D.y D.z |   | F.s F.t | | T.x T.y T.z |
    |             | = |         | |             |
    | E.x E.y E.z |   | G.s G.t | | U.x U.y U.z |
    

    反转FG矩阵的产量
    | T.x T.y T.z |           1         |  G.t  -F.t | | D.x D.y D.z |
    |             | = ----------------- |            | |             |
    | U.x U.y U.z |   F.s G.t - F.t G.s | -G.s   F.s | | E.x E.y E.z |
    

    顶点法线T和U与顶点法线形成局部空间基础,称为切线空间,由矩阵描述
    | T.x U.x N.x |
    | T.y U.y N.y |
    | T.z U.z N.z |
    

    从切线空间转换为对象空间。要进行照明计算,需要与此相反。通过一点点练习,您会发现:
    T' = T - (N·T) N
    U' = U - (N·U) N - (T'·U) T'
    

    归一化 vector T'和U',将它们称为切线和双法线,我们获得从对象到切线空间的变换矩阵,在此进行照明:
    | T'.x T'.y T'.z |
    | U'.x U'.y U'.z |
    | N.x  N.y  N.z  |
    

    我们将T'和U'与顶点法线存储在一起,作为模型几何的一部分(作为顶点属性),以便可以在着色器中使用它们进行照明计算。 ,我重复一遍:您无法在着色器中确定切线和双法线,而是对其进行预计算并将其存储为模型几何的一部分(就像法线一样)。

    (以上竖线之间的表示法都是矩阵,而不是行列式,通常使用竖线而不是方括号表示。)

    10-08 11:55