opengl es 2.0高光照明

时间:2013-05-11 15:47:22

标签: opengl-es-2.0 lighting fragment-shader specular

这是我在这里发表的第一篇文章,但是我正试图弄清楚这个问题。下面的代码是我的片段着色器,用于一个非常简单的Opengl es 2.0应用程序。顶点着色器正在执行所有常规业务。问题在于镜面高光,它是在每个顶点的基础上执行计算,而不是每个片段。如果有人能向我解释为什么会这样,我会非常感激。感谢。

顺便说一句,对于效率低下的代码,我很抱歉,我只是回到光照的基础上试图跟踪这个问题。

precision highp float;

struct DirectionLight
{
    vec4 Ambient;
    vec4 Diffuse;
    vec4 Specular;
};

struct Material
{
    vec4 Ambient;
    vec4 Diffuse;
    vec4 Specular;
    float SpecularExponent;
};

const float c_zero = 0.0;
const float c_one  = 1.0;

uniform DirectionLight   u_directionLight;
uniform Material         u_material;
uniform sampler2D        u_texture;
uniform vec3             u_lightPosition;
uniform vec3             u_eyePosition;

varying vec3             v_position;
varying vec3             v_normal;
varying vec2             v_texCoord;

void main()
{
    vec4 totalLight = vec4(c_zero, c_zero, c_zero, c_zero);
    vec4 ambient    = vec4(c_zero, c_zero, c_zero, c_zero);
    vec4 diffuse    = vec4(c_zero, c_zero, c_zero, c_zero);
    vec4 specular   = vec4(c_zero, c_zero, c_zero, c_zero);
    vec3 halfPlane  = vec3(c_zero, c_zero, c_zero);

    halfPlane = normalize(u_eyePosition + u_lightPosition);

    float distance    = length(u_lightPosition - v_position);
    float attenuation = c_one / (c_one + (0.1 * distance) + (0.01 * distance * distance));

    vec3 lightVector = normalize(u_lightPosition - v_position);

    float ndotl = max(dot(v_normal, lightVector), 0.1);
    float ndoth = max(dot(v_normal, halfPlane), 0.1);

    ambient = u_directionLight.Ambient * u_material.Ambient;
    diffuse = ndotl * u_directionLight.Diffuse * u_material.Diffuse;

    if(ndoth > c_zero)
    {
        specular = pow(ndoth, u_material.SpecularExponent) * u_directionLight.Specular * u_material.Specular;
    }

    totalLight = ambient + ((diffuse + specular) * attenuation);

    gl_FragColor = totalLight;// * (texture2D(u_texture, v_texCoord));
}

1 个答案:

答案 0 :(得分:0)