Modern GLSL ( opengl 3+ ) :正确实现 phong 效果;

Modern GLSL ( opengl 3+ ) : Implementing phong effect correctly;

我正在实现一个基本的 phong 照明 GLSL 着色器;我在互联网上查找了一些东西,发现 phong 效果是通过在对象上添加环境、漫反射和镜面反射层创建的(见下图,来自 tom dalling 的网站);问题是我看过很多示例,其中 none 确实适合我的 GLSL 设置。你们中的任何人都可以给我一个 实现 phong 效果 的正确方法的代码示例,它 适合我的 GLSL 设置 吗? :

PS:这个问题可以搁置,因为它可能基于用户意见:在我看来,它不是,因为我想知道最有效和更好的实施方法

这是我的顶点着色器:

#version 120

uniform mat4 modelView;
uniform mat4 MVP;
uniform float time;

attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;

varying vec3 position0;
varying vec2 texCoord0;
varying vec3 normal0;
varying mat4 modelView0;


void main()
{
    //Updating varyings...
    position0 = position;
    texCoord0 = texCoord;
    normal0 = (MVP * vec4(normal, 0.0)).xyz;
    modelView0 = modelView;

    //set position
    gl_Position = MVP *  vec4(position, 1.0);
} 

和我的片段着色器:

#version 120

varying vec3 position0;
varying vec2 texCoord0;
varying vec3 normal0;
varying mat4 modelView0;

uniform sampler2D diffuse;

void main()
{

    vec4 surfaceColor = texture2D(diffuse, texCoord0);
    gl_FragColor = (texture2D(diffuse, texCoord0))
        * clamp(dot(-vec3(0.0, 0.5, 0.5), normal0), 0, 1.0);

}

试试这个:

void main() 
{ 
    vec4 texread = texture2D(diffuse, texCoord0);
    vec3 normal = normalize(normal0);

    vec3 material_kd = vec3(1.0,1.0,1.0);
    vec3 material_ks = vec3(1.0,1.0,1.0);
    vec3 material_ka = vec3(0.2,0.2,0.2);
    vec3 material_ke = vec3(0.0,0.0,0.0);
    float material_shininess = 60;

    vec3 lightpos = vec3(0.0,10.0,5.0);
    vec3 lightcolor = vec3(1.0,1.0,1.0);

    vec3 lightdir = normalize(lightpos - worldPosition);

    float shade = clamp(dot(lightdir, normal), 0.0, 1.0); 
    vec3 toWorldpos = normalize((worldPosition) - u_eyePos); 
    vec3 reflectDir = reflect( toWorldpos, normal ); 

    vec4 specular = vec4(pow(clamp(dot(lightdir, reflectDir),0.0,1.0), material_shininess) * lightcolor * material_ks, 1.0); 
    vec4 shaded = texread * vec4(material_kd, 1.0) * vec4(lightcolor , 1.0) * shade;

    vec4 ambient = texread * vec4(material_ka, 1.0);
    vec4 emission = vec4(material_ke, 1.0);

    gl_FragColor = shaded + specular + emission + ambient;

}

它可能有一些编译错误,虽然我没有 运行 它...... 你可能需要上传你的眼睛位置作为制服 (u_eyePos),并计算世界位置 (worldPosition) 才能工作

我制作了自己的 sphong 着色器:这是代码:

片段着色器:

#version 150

uniform mat4 modelView;
uniform mat3 normalMatrix;
uniform vec3 cameraPosition;

uniform sampler2D materialTex;
uniform float materialShininess;
uniform vec3 materialSpecularColor;

uniform vec3 lightPosition;//light settings
uniform vec3 lightIntensities;
uniform float lightAttenuation;
uniform float lightAmbientCoeff;

in vec3 position0;
in vec2 texCoord0;
in vec3 normal0;

out vec4 fragmentColor;

void main()
{
    //calculate normal in world coordinates
    vec3 normal = normalize(normalMatrix * normal0);

    //calculate the location of this fragment (pixel) in world coordinates
    vec3 surfacePos = vec3(modelView * vec4(position0, 1));

    //color of the current fragment
    vec4 surfaceColor = texture(materialTex, texCoord0);


    //calculate the vector from this pixels surface to the light source
    vec3 surfaceToLight = normalize(lightPosition - surfacePos);

    //cam distance
    vec3 surfaceToCamera = normalize(cameraPosition - surfacePos);

    ///////////////////////////DIFUSE///////////////////////////////////////

    //calculate the cosine of the angle of incidence
    //float diffuseCoeff = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal));
    float diffuseCoeff = max(0.0, dot(normal, surfaceToLight));
    vec3 diffuse = diffuseCoeff * surfaceColor.rgb * lightIntensities;

    /////////////////////////AMBIENT////////////////////////////////////////
    vec3 ambient = lightAmbientCoeff * surfaceColor.rgb * lightIntensities;

    /////////////////////////SPECULAR//////////////////////////////////////
    float specularCoeff = 0.0;
    if(diffuseCoeff > 0.0)
        specularCoeff = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
    vec3 specular = specularCoeff * materialSpecularColor * lightIntensities;

    ////////////////////////ATTENUATION///////////////////////////////////
    float distanceToLight = length(lightPosition - surfacePos);
    float attenuation = 1.0 / (1.0 + lightAttenuation * pow(distanceToLight, 2));

    /////////////////////////////////FINAL/////////////////////////////////

    vec3 linearColor = ambient + attenuation * (diffuse +  specular);

    //finalColor with gamma correction
    vec3 gamma = vec3(1.0/2.2);
    fragmentColor = vec4(pow(linearColor, gamma), surfaceColor.a);
    //fragmentColor = vec4(diffuseCoeff * lightIntensities * surfaceColor.rgb, surfaceColor.a);
}