• <- OPENGL 10 NormalMAP ->


    复习基础知识

    1,GLSL Mat矩阵全部是列向量 优先构造矩阵。

    2,GLM同样以列为主:

    #include <iostream>
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    using namespace std;
    ostream
    & operator<<(ostream & os , const glm::mat4 &inputMat){ // col:1 row:1 col:2 row:1 col:3 row:1 col:4 row:1 cout << inputMat[0][0] <<" " <<inputMat[1][0] << " " <<inputMat[2][0] << " " << inputMat[3][0] << endl; // col:1 row:2 col:2 row:2 col:3 row:2 col:4 row:2 cout << inputMat[0][1] <<" " <<inputMat[1][1] << " " <<inputMat[2][1] << " " << inputMat[3][1] << endl; // col:1 row:3 col:2 row:3 col:3 row:3 col:4 row:3 cout << inputMat[0][2] <<" " <<inputMat[1][2] << " " <<inputMat[2][2] << " " << inputMat[3][2] << endl; // col:1 row:4 col:2 row:4 col:3 row:4 col:4 row:4 cout << inputMat[0][3] <<" " <<inputMat[1][3] << " " <<inputMat[2][3] << " " << inputMat[3][3] << endl; return os; } ostream & operator << (ostream &os , const glm::vec4 &vec){ cout << vec.x << " " << vec.y << " " << vec.z << " " <<vec.w ; return os; } void debug(const glm::mat4 &inputMat){ cout << "col 1->" <<inputMat[0] << endl; // access col 1 cout << "col 2->" <<inputMat[1] << endl; // access col 2 cout << "col 3->" <<inputMat[2] << endl; // access col 3 cout << "col 4->" <<inputMat[3] << endl; // access col 4 } int main() { glm::mat4 m01(1.0f); cout << m01 <<endl; // use array to construct matrix glm::mat4 m02(1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16); cout << m02 << endl; // Use vector to construct matrix glm::mat4 m03(glm::vec4(1,1,1,1), glm::vec4(2,2,2,2), glm::vec4(3,3,3,3), glm::vec4(4,4,4,4)); cout << m03 << endl; debug(m03); return 0; }

    结果:

    D:plugin_devopenglglm_testCP_01cmake-build-debugCP_01.exe
    1 0 0 0
    0 1 0 0
    0 0 1 0
    0 0 0 1
    
    1 5 9 13
    2 6 10 14
    3 7 11 15
    4 8 12 16
    
    1 2 3 4
    1 2 3 4
    1 2 3 4
    1 2 3 4
    
    col 1->1 1 1 1
    col 2->2 2 2 2
    col 3->3 3 3 3
    col 4->4 4 4 4
    
    Process finished with exit code 0

    3,同样观查GLM源码,operator[]确实返回列为主得向量

    4,把GLM向量放到vector中,展平访问:

    #include <iostream>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <glm/glm.hpp>
    #include <vector>
    using namespace std;
    
    int main()
    {
        vector <glm::vec3> points;
        points.emplace_back(glm::vec3(1,2,3));
        points.emplace_back(glm::vec3(4,5,6));
        points.emplace_back(glm::vec3(7,8,9));
    
        float *dataPointer = (float*) (points.data()); 
    
        cout << *( dataPointer + 0)  << endl; // -> 1
        cout << *( dataPointer + 1)  << endl; // -> 2
        cout << *( dataPointer + 2)  << endl; // -> 3
        cout << *( dataPointer + 3)  << endl; // -> 4
        return 0;
    }

    5,而我们houdini却是个用行向量。

    6, NormalMap:

    Houdini需要normalMalMap:

     OPENGL需要的NormalMap,可以看到Y轴向是反的:

    https://learnopengl-cn.github.io/05%20Advanced%20Lighting/04%20Normal%20Mapping/ 给的贴图必须在Houdini下选择linear 模式。

    首先 法线贴图是在切线空间,在切线空间法线全部对齐z轴向

    用houdini理解最简单,平常一个物体比如box对齐到z轴向。如图:

    如果把这玩意拷贝到球上:相当于将把长方体 转到 法线形成的正交矩阵空间,此时这个法线空间就是我们的世界空间,(一般用个up向量这个球上法线形成3个正交向量就行,但是也可以是TBN矩阵):

     当然转到 这个球的法线空间(世界物体法线空间),也可以形成TBN正交矩阵: 

    Houdini IMP the normalMap at world space:

    float blinn(vector cameraP; vector P; vector N; vector LgtP){
        vector wo = normalize(cameraP - P);
        vector wi = normalize(LgtP - P);
        vector nn = normalize(N);
        // cal the blinn specular
        vector h = normalize(wi + wo);
        float ndoth = max(dot(nn,h),0.0f);
        float blinn_brdf = pow(ndoth,60.0f) ;
        return blinn_brdf;
    }
    
    
    blinnbrdf = blinn(camP,P,N,lgtP);
    blinn

    所以:

    1,只要把 TBN矩阵 * 法线贴图形成的vector   相当于把法线贴图转到真正的 世界空间可以直接用的法线,此时这个法线做灯光用,细节多的一批。 

    2,也可以直接把世界空间的向量(比如灯光向量)变换到这个法线贴图所在的 切线空间。方法就是TBN的逆矩阵 * 灯光向量,而正交矩阵的逆矩阵=正交矩阵的转置矩阵,求逆矩阵运算量太大,所以教程中也是转到转置矩阵。接下来就是正常的材质运算。

  • 相关阅读:
    Hello, Fedora.
    Android与Linux分道扬镳
    VIM教程V1.5梁昌泰
    强大的NTFS文件系统
    Linux下的cc与gcc
    g++与gcc的区别
    Fedora下解压缩的相关问题
    The GNU C Reference Manual
    Linux Kbuild文档
    实验一:计算机是怎样工作的
  • 原文地址:https://www.cnblogs.com/gearslogy/p/12545438.html
Copyright © 2020-2023  润新知