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

时间:2015-06-10 19:12:09

标签: glsl opengl-3

我正在实施基本的phong照明GLSL着色器;我在互联网上查了一些东西,发现phong效果是通过在对象上添加环境,漫反射和高光层来创建的(见下图,来自tom dalling' s网站);问题是我看过很多例子,其中没有一个真的适合我的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);

}

enter image description here

2 个答案:

答案 0 :(得分:1)

试试这个:

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 )以使其正常工作

答案 1 :(得分:0)

我制作了自己的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);
}