flat 和 phong 着色问题

Posted

技术标签:

【中文标题】flat 和 phong 着色问题【英文标题】:Problems with flat and phong shading 【发布时间】:2013-05-31 02:16:56 【问题描述】:

(编辑):我发布的原始代码用于 gouraud 和 phong 着色选项。我已经改变了它,所以它只是 phong 阴影并发布在下面。网格太大,无法在此处描述,因为它是从 Bezier Patch 生成的。

我在 Open GL 3 Mesa 9 中遇到了一些平面和 phong 阴影问题。似乎无论我做什么,我都会得到平面阴影图形,带有微小的刻面(平面),我无法让 Blinn-Phong 阴影工作.

这是我的着色器:

(顶点着色器)

//material parameters

uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform float Shininess;


attribute vec4 vPosition;
//attribute vec4 vColor;
attribute vec4 vNormal;
attribute vec4 vControlColor;
attribute vec2 texcoord;


uniform mat4 model_view;
uniform mat4 projection;

uniform int flag;
uniform int phong_flag;
uniform vec4 eye_position;

//lighting parameters
uniform vec4 light_1;               //light 1 position         
uniform vec4 light_2;               //light 2 position



varying vec4 control_color;
varying vec4 color;
varying vec4 position;
varying vec4 normal;

varying vec2 st;

void
main()


    control_color = vControlColor;
    position = vPosition;
    normal = vNormal;
    tex_coords = texcoord;
    st = texcoord;
    gl_Position = projection*model_view*vPosition;


还有我的片段着色器:

//material parameters

uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform float Shininess;
uniform vec4 eye_position;

uniform int phong_flag;


//lighting parameters
uniform vec4 light_1;               //light 1 position         
uniform vec4 light_2;               //light 2 position
varying vec4 light_2_transformed;   //light 2 transformed position
uniform int Control_Point_Flag;
uniform sampler2D texMap;

varying vec4 color;
varying vec4 position;
varying vec4 normal;
varying vec4 control_color;

varying vec2 st;

void
main()


        vec4 N = normalize(normal);
        vec4 E = normalize(eye_position - position);
        vec4 L1 = normalize(light_1 - position);
        vec4 L2 = normalize(light_2 - position);
        vec4 H1 = normalize( L1 + E);
        vec4 H2 = normalize( L2 + E);

        //calculate ambient component
        vec4 ambient = AmbientProduct;


        //calculate diffuse componenent
        float k_d_1 = max(dot(L1,N), 0.0);
        float k_d_2 = max(dot(L2,N), 0.0);
        vec4 diffuse1 = k_d_1*DiffuseProduct;
        vec4 diffuse2 = k_d_2*DiffuseProduct;

        //calculate specular componenent
        float k_s_1 = pow(max(dot(N, H1), 0.0), Shininess);
        float k_s_2 = pow(max(dot(N, H2), 0.0), Shininess);
        vec4 specular1 = k_s_1*SpecularProduct;
        vec4 specular2 = k_s_2*SpecularProduct;   

        //if specular color is behind the camera, discard it
        if (dot(L1, N) < 0.0) 
            specular1 = vec4(0.0, 0.0, 0.0, 1.0);
        
        if (dot(L2, N) < 0.0) 
            specular2 = vec4(0.0, 0.0, 0.0, 1.0);
        


        vec4 final_color = ambient + diffuse1 + diffuse2 + specular1 + specular2;

        final_color.a = 1.0;

        /* gl_FragColor = final_color; */
        gl_FragColor = final_color*texture2D(texMap, st);


我的着色器看起来一切正常吗?

【问题讨论】:

降低着色器的复杂性是一个好的开始。这是一个巨大的调试混乱。发布紧凑且可读的代码也是一个好主意。 你的网格是什么样子的? 你的#version指令在哪里? 【参考方案1】:

注意事项:

    您的顶点着色器中有 ModelView 的变量,但您从未在计算中使用它 position。因此,您的顶点“position”是从您的 OpenGL 应用程序传递的任何内容,并且不受您可能尝试执行的任何转换的影响,尽管它们在物理上放置正确,因为您使用了 gl_Position 的矩阵。 您没有将 法线矩阵 传递给您的着色器。 Normal 矩阵是通过 ModelView 矩阵的转置逆来计算的。在着色器外部计算并将其传入。如果您不将法线乘以法线矩阵,您仍然可以转换模型,但法线仍将面向相同的方向,因此您的照明将是不正确的。

但是,您在 OpenGL 端的法线向量可能是罪魁祸首。请参阅this question,了解可能导致不想要的平面阴影的来源。

附带说明,您的两个着色器似乎都比应有的复杂。也就是说,它们有太多未使用的变量和太多可以压缩成更少行的东西。这只是家务,但它会让您更轻松地跟踪您的代码。

【讨论】:

Umm... 1) 这只是着色器代码,不是应用程序代码。在我的应用程序中,我确实通过显示回调中的 Uniform 变量传递了模型视图和投影矩阵。法线与几何图形一起通过 vbo 传入。另外,2,如果我传递法线向量,我被告知不需要法线矩阵。您所说的这段代码过于复杂,是直接取自 GL 教科书,不一定都是我的。我会查看您提供的链接。 1) 这在你原来的问题中很明显。 2) 我根据我用过的着色书给你建议。您可以阅读this question 了解有关矩阵的一些理由。

以上是关于flat 和 phong 着色问题的主要内容,如果未能解决你的问题,请参考以下文章

Phong 着色器不起作用

顶点着色器中的 Phong 光照

在我的着色器中实现 phong 着色(过度纹理)的错误

WebGL三维模型实现Phong着色(WebGL进阶05)

Phong 着色模型

如何在 OpenGL 中为 Phong 着色插入法线?