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

现代GLSL(OpenGL3+;):正确实现phong效果;,glsl,opengl-3,Glsl,Opengl 3,我正在实现一个基本的phong lighting GLSL着色器;我在网上查了一些东西,发现phong效果是通过在对象上添加环境光、漫反射和镜面反射层而产生的(见下图,来自tom dalling的网站);问题是我见过很多例子,但没有一个真正适合我的GLSL设置。你们谁能给我一个实施phong效果的正确方法的代码示例,该方法符合我的GLSL设置 PS:这个问题可能会被搁置,因为它可能基于用户意见:在我看来,它不是,因为我想知道实施它的最有效、更好的方法 这是我的顶点着色器: #version 12

我正在实现一个基本的phong lighting GLSL着色器;我在网上查了一些东西,发现phong效果是通过在对象上添加环境光、漫反射和镜面反射层而产生的(见下图,来自tom dalling的网站);问题是我见过很多例子,但没有一个真正适合我的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);

}
#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);
}
和我的片段着色器:

#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);

}
#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);
}
试试这个:

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(worldposition)以使其工作

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

片段着色器:

#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);

}
#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);
}

试试这个谢谢:)我用世界空间解决了这个问题,但这是个好方法,所以我用这个。眼睛位置是相机位置吗?好的,谢谢!我会发布我的版本:你能告诉我如何改进吗:)