- 假设所有光线都是平行的,所以只需要计算一个物体和光源的角度就可以了(不需要在顶点或者片段着色器中进行计算了)

- 修改片段着色器中光的属性position变为齐次坐标
uniform vec4 lightPos;
struct Light{
vec4 lightDir;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
light.lightDir = lightPos;
light.ambient =vec3(0.2);
light.diffuse =vec3(0.6);
light.specular =vec3(1.0);
vec3 lightDirction;
if(light.lightDir.w == 0)
lightDirction =normalize( vec3(light.lightDir));
else if(light.lightDir.w == 1)
lightDirction = normalize(vec3(light.lightDir) - FragPos);
glUniform4f(glGetUniformLocation(cubeShader.ID, "lightPos"), cubePositions[1].r, cubePositions[1].g, cubePositions[1].b,1);
- 注意大部分的时候光源的方向是光源指向点的方向所以要取反

- 光线强弱的衰减
- 这里使用两个立方体进行比较
glm::vec3 cubePositions[] = {
glm::vec3(0.0f,0.0f,0.0f),
glm::vec3(2.0f, 0.0f, 2.0f),
glm::vec3(-3.0f, 1.0f, -2.0f),
};
glBindVertexArray(cubeVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
model = glm::translate(trans, cubePositions[2]);
glUniformMatrix4fv(glGetUniformLocation(cubeShader.ID, "model"), 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 36);

#version 400 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoords;
uniform vec3 lightColor;
uniform vec3 objectColor;
uniform vec4 lightPos;
uniform vec3 viewPos;
uniform sampler2D ourTexture1;
uniform sampler2D ourTexture2;
struct Material{
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
Material material;
struct Light{
vec4 lightDir;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
};
Light light;
void main()
{
material.ambient = vec3(texture(ourTexture1,TexCoords));
material.diffuse = vec3(texture(ourTexture1,TexCoords));
material.specular = vec3(texture(ourTexture2,TexCoords));
material.shininess = 32;
light.lightDir = lightPos;
light.ambient =vec3(0.2);
light.diffuse =vec3(0.6);
light.specular =vec3(1.0);
light.constant = 1.0;
light.linear = 0.09;
light.quadratic = 0.032;
float distance;
vec3 lightDirction;
if(light.lightDir.w == 0)
lightDirction =normalize(vec3(light.lightDir));
else if(light.lightDir.w == 1){
distance = length(vec3(light.lightDir) - FragPos);
lightDirction = (vec3(light.lightDir) - FragPos)/length(vec3(light.lightDir) - FragPos);
}
float attenuation = 1.0/(light.constant+light.linear*distance+light.quadratic*distance*distance);
float diffuse = max(dot(Normal,lightDirction),0.0);
vec3 viewDirction = normalize(viewPos - FragPos);
vec3 reflectDirction = reflect(-lightDirction,Normal);
float specular = pow(max(dot(reflectDirction,viewDirction),0.0),32);
FragColor = vec4((light.ambient*material.ambient
+diffuse*light.diffuse*material.diffuse
+specular*light.specular*material.specular)*lightColor*attenuation, 1.0);
}
- 衰减后的效果比较
