Phong reflection model: ADS(Ambient Diffuse Specular)¶
n: n ormal vector at the surface point.
s: the direction from the surface point to light s ource.
Ld: light intensity.
Kd: surface diffuse reflection.
Intensity = Ld x Kd (n dot s)
VertexADS(Ambient, Diffuse, Specular)¶
struct VS_IN {
float3 POSITION : POSITION;
float3 NORMAL : NORMAL;
};
struct PS_IN {
float4 POSITION : SV_POSITION;
float3 COLOR : COLOR0;
};
struct LightInfo {
// w == 1 ? point : directional
float4 Position;
float4 Intensity;
};
row_major float4x4 ModelViewMatrix : WORLDVIEW;
row_major float3x4 NormalMatrix : NORMAL_MATRIX;
row_major float4x4 MVP : WORLDVIEWPROJECTION;
LightInfo Lights[5] : LIGHT_LIST;
float3 Kd : MATERIAL_COLOR;
float3 Ka : MATERIAL_AMBIENT;
float4 Ks : MATERIAL_SPECULAR;
float lambert(float3 n, float3 s) { return max(dot(n, s), 0); }
float specular(float3 n, float3 s, float3 v) {
float3 r = reflect(-s, n);
return pow(max(dot(r, v), 0), Ks.w);
}
float3 lightVector(LightInfo light, float3 viewPosition) {
if (light.Position.w == 0) {
return normalize(-mul(light.Position.xyz, NormalMatrix));
} else {
float3 light_position = mul(light.Position, ModelViewMatrix).xyz;
return normalize(light_position - viewPosition);
}
}
float3 ads(LightInfo light, float3 viewPosition, float3 n) {
float3 s = lightVector(light, viewPosition);
return light.Intensity * (Ka //
+ Kd * lambert(n, s) //
+ Ks * specular(n, s, normalize(-viewPosition)));
}
PS_IN vsMain(VS_IN IN) {
float3 viewNormal = normalize(mul(IN.NORMAL, NormalMatrix));
float3 viewPosition = mul(float4(IN.POSITION, 1), ModelViewMatrix).xyz;
PS_IN OUT;
OUT.COLOR = float3(0, 0, 0);
OUT.COLOR += ads(Lights[0], viewPosition, viewNormal);
OUT.COLOR += ads(Lights[1], viewPosition, viewNormal);
OUT.COLOR += ads(Lights[2], viewPosition, viewNormal);
OUT.COLOR += ads(Lights[3], viewPosition, viewNormal);
OUT.COLOR += ads(Lights[4], viewPosition, viewNormal);
OUT.POSITION = mul(float4(IN.POSITION, 1), MVP);
return OUT;
}
float4 psMain(PS_IN IN) : SV_TARGET { return float4(IN.COLOR, 1); }