# 【一步步学OpenGL 19】 -《镜面反射光》

## 镜面反射光

### 背景

‘I’ 是入射光

‘N’ 是表面法线

‘R’ 反射光，和入射光’I’关于法线对称，但方向相反

‘V’ 是从入射光和反射光交点处（入射点）到观察者眼睛的向量，表示观察者视线

‘α’ 反射光’R’和观察者视线’V’的夹角

### 源代码详解

(lighting_technique.h:32)


class LightingTechnique : public Technique
{
public:
...
void SetEyeWorldPos(const Vector3f& EyeWorldPos);
void SetMatSpecularIntensity(float Intensity);
void SetMatSpecularPower(float Power);

private:
...
GLuint m_eyeWorldPosLocation;
GLuint m_matSpecularIntensityLocation;
GLuint m_matSpecularPowerLocation;
}


(lighting.vs:12)


out vec3 WorldPos0;

void main()
{
gl_Position = gWVP * vec4(Position, 1.0);
TexCoord0 = TexCoord;
Normal0 = (gWorld * vec4(Normal, 0.0)).xyz;
WorldPos0 = (gWorld * vec4(Position, 1.0)).xyz;
}



(lighting.fs:5)
in vec3 WorldPos0;
.
.
.
uniform vec3 gEyeWorldPos;
uniform float gMatSpecularIntensity;
uniform float gSpecularPower;

void main()
{
vec4 AmbientColor = vec4(gDirectionalLight.Color * gDirectionalLight.AmbientIntensity, 1.0f);
vec3 LightDirection = -gDirectionalLight.Direction;
vec3 Normal = normalize(Normal0);

float DiffuseFactor = dot(Normal, LightDirection);

vec4 DiffuseColor = vec4(0, 0, 0, 0);
vec4 SpecularColor = vec4(0, 0, 0, 0);

if (DiffuseFactor > 0) {
DiffuseColor = vec4(gDirectionalLight.Color, 1.0f) *
gDirectionalLight.DiffuseIntensity *
DiffuseFactor;

vec3 VertexToEye = normalize(gEyeWorldPos - WorldPos0);
vec3 LightReflect = normalize(reflect(gDirectionalLight.Direction, Normal));
float SpecularFactor = dot(VertexToEye, LightReflect);
if (SpecularFactor > 0) {
SpecularFactor = pow(SpecularFactor, gSpecularPower);
SpecularColor = vec4(gDirectionalLight.Color * gMatSpecularIntensity * SpecularFactor, 1.0f);
}
}

FragColor = texture2D(gSampler, TexCoord0.xy) * (AmbientColor + DiffuseColor + SpecularColor);
}


(tutorial19.cpp:134)


m_pEffect->SetEyeWorldPos(m_pGameCamera->GetPos());
m_pEffect->SetMatSpecularIntensity(1.0f);
m_pEffect->SetMatSpecularPower(32);