V1.0 2017.10.30

# 基础光照

• 环境光照(Ambient Lighting)：即使在黑暗的情况下，世界上通常也仍然有一些光亮（月亮、远处的光），所以物体几乎永远不会是完全黑暗的。为了模拟这个，我们会使用一个环境光照常量，它永远会给物体一些颜色。

• 漫反射光照(Diffuse Lighting)：模拟光源对物体的方向性影响(Directional Impact)。它是冯氏光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源，它就会越亮。

• 镜面光照(Specular Lighting)：模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。

# 环境光照

``````void main()
{
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;

vec3 result = ambient * objectColor;
FragColor = vec4(result, 1.0);
}
``````

# 漫反射光照

• 法向量：一个垂直于顶点表面的向量。
• 定向的光线：作为光源的位置与片段的位置之间向量差的方向向量。为了计算这个光线，我们需要光的位置向量和片段的位置向量。

# 法向量

``````#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
...
``````

``````glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
``````

``````out vec3 Normal;

void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
Normal = aNormal;
}
``````

``````in vec3 Normal;
``````

# 计算漫反射光照

``````uniform vec3 lightPos;
``````

``````lightingShader.setVec3("lightPos", lightPos);
``````

``````out vec3 FragPos;
out vec3 Normal;

void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = aNormal;
}
``````

``````in vec3 FragPos;
``````

``````vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
``````

``````float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
``````

``````vec3 result = (ambient + diffuse) * objectColor;
FragColor = vec4(result, 1.0);
``````

# 最后一件事

``````Normal = mat3(transpose(inverse(model))) * aNormal;
``````

# 镜面光照

``````uniform vec3 viewPos;
``````
``````lightingShader.setVec3("viewPos", camera.Position);
``````

``````float specularStrength = 0.5;
``````

``````vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
``````

``````float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
``````

``````vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);
``````