Create a Shader to Implement the Phong and Blinn-Phong Specular Lighting.
Solution:
1.Study of the Phong Specular Lighting from <<Introduction to 3D Game Programming with DirectX 10>>
2.the Blinn Modification to Phong
the major different between Phong and Blinn is the H(Half) vector, Phong calculate reflectance between R and V, the Blinn calculate with H and N(Normal).
3.Shader Source
float4x4 wvp : WorldViewProjection <string UIWidget="None" ;>; float4x4 w : World <string UIWidget="None";>; float4x4 vi: ViewInverse <string UIWidget="None";>; float4 LightPosition : POSITION < string UIName="Light Position"; string Object="PointLight"; string Space="World"; int refID=0; > =float4(100,100,100,0); float4 LightColor: LIGHTCOLOR < int LightRef=0; > =float4(1,1,1,0); float Glossiness < string UIName="Glossiness"; int UIMin=1; int UIMax=99; int UIStep=1; > = 0; float SpecularLevel < string UIName="Specular Level"; int UIMin=0; int UIMax=99; int UIStep=1; > = 0; bool EnableSpecular < string UIName="Enable Specular Lighting"; > = true; struct VS_INPUT { float4 Pos: POSITION; float4 Normal: NORMAL; }; struct VS_OUTPUT { float4 Pos : POSITION0; float3 L: TEXCOORD0; float3 N: TEXCOORD1; float3 V: TEXCOORD2; }; VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Result; Result.Pos = mul(Input.Pos,wvp); float3 worldPos=mul(Input.Pos,w); Result.L=LightPosition-worldPos; Result.N=mul(Input.Normal,w); Result.V=vi[3]-worldPos; return Result; } float4 ps_main(VS_OUTPUT Input):COLOR { float3 N=normalize(Input.N); float3 L=normalize(Input.L); float3 V=normalize(Input.V); float3 H=normalize(L+V); float NdotL=max(0.0f,dot(N,L)); float NdotH=max(0.0f,dot(H,N)); float3 Diffuse=LightColor*NdotL; float3 Specular=EnableSpecular?Glossiness*pow(NdotH,SpecularLevel):0; return float4(Diffuse+Specular,1); } float4 ps_phong_main(VS_OUTPUT Input):COLOR { float3 N=normalize(Input.N); float3 L=normalize(Input.L); float3 V=normalize(Input.V); float3 R=-reflect(L,N); float NdotL=max(0,dot(N,L)); float RdotV=max(0,dot(R,V)); float3 Diffuse=LightColor*NdotL; float3 Specular=EnableSpecular?Glossiness*pow(RdotV,SpecularLevel):0; return float4(Diffuse+Specular,1); } technique BlinnSpecular { pass Blinn { VertexShader = compile vs_2_0 vs_main(); PixelShader = compile ps_2_0 ps_main(); } }; technique PhongSpecular { pass Phong { VertexShader = compile vs_2_0 vs_main(); PixelShader = compile ps_2_0 ps_phong_main(); } };
4.Preview
Specular lighting disabled
Phong and Blinn compares
Phong
Blinn
Phong
Blinn
Phong
Blinn