aaaa0ggmc_ 2023-04-11 08:03 采纳率: 33.3%
浏览 10

GLSL BlinnPhong优化到底有多少

James Blinn 发现Phong着色中求光线与平面的反射向量是不必要的,于是我的一本书《Computer Grapphics Programming in OpenGL with C++》说Blinn-Phong模型性能提升十分十分大,然而反射向量求解似乎也不是很难:

vec4 reflect(vec4 v,vec4 n){
  //求投影向量
  vec4 projV = dot(v,n)/(n.x*n.x+n.y*n.y+n.z*n.z)*n;
  return v - 2*projV;
}

现在随便一处不优化的code都比求reflect复杂

  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2023-04-11 08:36
    关注

    以下内容部分参考ChatGPT模型:


    BlinnPhong着色模型的优化可以从多个方面入手,例如:

    1. 使用预计算的法向量:在每个片元中计算法向量是比较耗时的,可以在顶点着色器中计算好法向量并传递给片元着色器使用。

    2. 使用预计算的半向量:BlinnPhong模型中需要计算半向量,可以在顶点着色器中计算好并传递给片元着色器使用。

    3. 精简计算公式:BlinnPhong模型中的计算公式比较复杂,可以通过简化一些公式来提高性能,例如可以通过移除一些不必要的指数运算来减少计算量。

    4. 使用纹理采样:可以通过在纹理中存储反射率和粗糙度等信息,来减少对光照计算的依赖,从而提高性能。

    5. 光源优化:可以通过减少光源的数量、使用较小的光源范围、使用光源的阴影优化等方式来提高性能。

    例子:

    下面是一个简化了的BlinnPhong着色器代码,其中使用了预计算的法向量和半向量:

    顶点着色器:

    #version 330 core
    
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aNormal;
    
    out vec3 FragPos;
    out vec3 Normal;
    out vec3 ViewDir;
    out vec3 HalfDir;
    
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    void main()
    {
        gl_Position = projection * view * model * vec4(aPos, 1.0);
        FragPos = vec3(model * vec4(aPos, 1.0));
        Normal = mat3(transpose(inverse(model))) * aNormal;
        ViewDir = vec3(0.0, 0.0, 1.0) - FragPos;
        HalfDir = normalize(ViewDir + vec3(0.0, 0.0, 1.0));
    }
    

    片元着色器:

    #version 330 core
    
    in vec3 FragPos;
    in vec3 Normal;
    in vec3 ViewDir;
    in vec3 HalfDir;
    
    out vec4 FragColor;
    
    uniform vec3 lightPos;
    uniform vec3 lightColor;
    uniform vec3 viewPos;
    uniform float shininess;
    
    void main()
    {
        vec3 lightDir = normalize(lightPos - FragPos);
        float diffuse = max(dot(Normal, lightDir), 0.0);
        vec3 reflectDir = reflect(-lightDir, Normal);
        float specular = pow(max(dot(HalfDir, reflectDir), 0.0), shininess);
        vec3 ambient = vec3(0.1, 0.1, 0.1);
        vec3 diffuseColor = vec3(1.0, 0.0, 0.0);
        vec3 specularColor = vec3(1.0, 1.0, 1.0);
        vec3 result = ambient + diffuseColor * diffuse + specularColor * specular;
        FragColor = vec4(result, 1.0);
    }
    

    如果我的建议对您有帮助、请点击采纳、祝您生活愉快

    评论

报告相同问题?

问题事件

  • 创建了问题 4月11日

悬赏问题

  • ¥15 github上的这个C语言项目如何跑起来
  • ¥15 java 判断某个数 区间是否存在
  • ¥15 appium控制多个雷电模拟器问题
  • ¥15 C# iMobileDevice
  • ¥15 谁会做这个啊#ensp#Boson NetSim
  • ¥15 如何编写针对TPS6503320FRGE型号的电源管理芯片的编程代码?
  • ¥15 设计简单目录管理系统,要满足以下内容
  • ¥15 关于九十度混合耦合器信号分析问题
  • ¥15 Cesm如何关闭不用的模块呢
  • ¥15 vue2两层数据导出为excle