平阴影和平阴影的问题

Problems with flat and phong shading

本文关键字:阴影 问题      更新时间:2023-10-16

(编辑):我发布的原始代码是为gouraud和phong着色选项。我已经改变了它,所以它只是phong阴影和张贴在下面。网格太大,无法在这里描述,因为它是由贝塞尔补丁生成的。

我在Open GL 3 Mesa 9中有一些平面和平面阴影的问题。似乎无论我怎么做,我得到的都是带有小平面(平面)的平面阴影,而且我无法使用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);
}

我的着色器看起来一切都好吗?

值得注意的事情:

  1. 你有一个ModelView在你的顶点着色器的变量,但你从来没有使用它在计算 position。因此,你的顶点"position"是任何从你的OpenGL应用程序传递的,不受你可能试图做的任何转换的影响,尽管它们是物理上正确放置的,因为你使用gl_Position的矩阵。
  2. 你没有传递一个正常矩阵到你的着色器。通过取ModelView矩阵的转置逆来计算Normal矩阵。在着色器外计算并传入。如果你没有将法线乘以法线矩阵,你仍然可以变换你的模型,但是法线仍然会朝向相同的方向,所以你的照明将是不正确的。

然而,你在OpenGL方面的法向量可能是罪魁祸首。关于不需要的平面阴影的可能来源,请参阅这个问题。

作为旁注,你的着色器似乎比他们应该更复杂。也就是说,它们有太多没有使用的变量和太多可以压缩成更少行的东西。这只是内务管理,但它将使跟踪代码更容易。