keywords：ambient diffuse specular、Phong Shading、Phong reflection model

#### 公式概述

LightIntensity = Ambient + Diffuse + Specular;


• Ambient 环境光
• Diffuse 漫反射
• Specular 全反射光 / 镜面光

Ambient = La * Ka;
Diffuse = Ld * Kd * max( dot(s, n), 0.0 );
Specular = Ls * Ks * pow( max( dot(r, v), 0.0 ), f );


• La 环境光强度(Ambient light intensity)
• Ka 材质环境光反射率 / 材质环境光反射系数(Ambient reflectivity)
• Ld 漫射光强度 / 散射光强度(Diffuse light intensity)
• Kd 材质漫反射率 / 材质漫反射系数(Diffuse reflectivity)
• s 顶点 / 曲面点 到光源方向的单位向量(Direction from the surface point to the light source)
• n 顶点 / 曲面点 的法线单位向量(Normal vector at the surface point)
• Ls 镜面光强度 / 全反射光强度(Specular light intensity)
• Ks 材质镜面反射率 / 材质镜面反射系数(Specular reflectivity)
• r 完全反射向量( the vector of perfect reflection)
• v 顶点 / 曲面点 到摄像机方向的向量( the vector towards the viewer)
• f 镜面高光(specular highlights)，值范围在1到200之间，值越小，镜面亮点越大

#### 渲染实例

OpenGL API 版本为4.1。

diffuse.vert

#version 410

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;

out vec3 LightIntensity;

uniform vec4 LightPosition; // Light position in eye coords.
uniform vec3 Kd;            // Diffuse reflectivity
uniform vec3 Ld;            // Diffuse light intensity

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;

void main()
{
vec3 tnorm = normalize( NormalMatrix * VertexNormal);
vec4 eyeCoords = ModelViewMatrix * vec4(VertexPosition,1.0);
vec3 s = normalize(vec3(LightPosition - eyeCoords));

LightIntensity = Ld * Kd * max( dot( s, tnorm ), 0.0 );

gl_Position = MVP * vec4(VertexPosition,1.0);
}


diffuse.frag

#version 410

in vec3 LightIntensity;

layout( location = 0 ) out vec4 FragColor;

void main() {
FragColor = vec4(LightIntensity, 1.0);
}


phong.vert

#version 410

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;

out vec3 LightIntensity;

struct LightInfo {
vec4 Position; // Light position in eye coords.
vec3 La;       // Ambient light intensity
vec3 Ld;       // Diffuse light intensity
vec3 Ls;       // Specular light intensity
};
uniform LightInfo Light;

struct MaterialInfo {
vec3 Ka;            // Ambient reflectivity
vec3 Kd;            // Diffuse reflectivity
vec3 Ks;            // Specular reflectivity
float Shininess;    // Specular shininess factor
};
uniform MaterialInfo Material;

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;

void main()
{
vec3 tnorm = normalize( NormalMatrix * VertexNormal);
vec4 eyeCoords = ModelViewMatrix * vec4(VertexPosition,1.0);
vec3 s = normalize(vec3(Light.Position - eyeCoords));
vec3 v = normalize(-eyeCoords.xyz);
vec3 r = reflect( -s, tnorm );
float sDotN = max( dot(s,tnorm), 0.0 );
vec3 ambient = Light.La * Material.Ka;
vec3 diffuse = Light.Ld * Material.Kd * sDotN;
vec3 spec = vec3(0.0);
if( sDotN > 0.0 )
spec = Light.Ls * Material.Ks *
pow( max( dot(r,v), 0.0 ), Material.Shininess );

LightIntensity = ambient + diffuse + spec;
gl_Position = MVP * vec4(VertexPosition,1.0);
}


phong.frag

#version 410

in vec3 LightIntensity;

layout( location = 0 ) out vec4 FragColor;

void main() {
FragColor = vec4(LightIntensity, 1.0);
}


在各种事物的常理中，爱情是无法改变和阻挡的，因为就本性而言，爱只会自行消亡，任何计谋都难以使它逆转。---意大利·薄伽丘《十日谈》