首先,一个最重要的光照模型Lambert,图在第434页,R=2(N(点乘)L)N-L,,的是反射光向量,N是法线向量,L是逆光源向量.
另外,可以使用Blinn模型来模拟反射光,H=(L+V)/|L+V|.
高洛德着色的过程大概如下:
VS着色器:
VS_OUTPUT Out = (VS_OUTPUT)0;
float3 L = -lightDir;
//把顶点坐标和法线向量变换到摄像机坐标系
float4x4 WorldView = mul(World, View);
float3 P = mul(float4(Pos, 1), (float4x3)WorldView); // position (view space)
float3 N = normalize(mul(Norm, (float3x3)WorldView)); // normal (view space)
//计算反射光向量
float3 V = -normalize(P); // view direction (view space)
float3 R = normalize(2 * dot(N, L) * N - L); // reflection vector (view space)
// float3 R = normalize(L+V); Blinn光照模型 // reflection vector (view space)
//输出
Out.Pos = mul(float4(P, 1), Projection); // position (projected)
//计算漫反射强度时,取max(0,dot(N,L))是因为当L和N的夹角大于90度时,将没有漫反射光,而只有表示最小亮度的环境光
Out.Diff = I_a * k_a + I_d * k_d * max(0, dot(N, L)); // diffuse + ambient
//计算反射光时同样要注意当R和视线V夹角大于90度时反射光强度将为0
//另外要注意镜面反射光强度为I_s*K_s*pow(cosX,n),X是R与V的夹角,,在这里因为R,V都是单位向量,因此dot(R,V)=cosX
Out.Spec = I_s * k_s * pow(max(0, dot(R, V)), n/4); // specular
Out.Tex = Tex;
return Out;
PS着色器:
float4 PS(
float4 Diff : COLOR0,
float4 Spec : COLOR1,
float2 Tex : TEXCOORD0) : COLOR
{
//纹理颜色*漫反射光强度+反射光
return tex2D(Sampler, Tex) * Diff + Spec;
}