图形学界大牛Jim Blinn对Phong模型进行了改进,提出了Blinn-Phong模型。Blinn-Phong模型与Phong模型的区别是,把dot(V,R)换成了dot(N,H),其中H为半角向量,位于法线N和光线L的角平分线方向。Blinn-Phong模型可表示为:

          Ispecular = Ks*Is* pow(( dot(N,H), n )

其中H = (L + V) / | L+V |,计算H比计算反射向量R更快速。

1) VertexShader

float4x4 matWorldViewProjection;

float4x4 matWorldView;

float4x4 matView;

float3 lightPos;


struct VS_INPUT
{
float4 position : POSITION0;
float3 normal: NORMAL;
};

struct VS_OUTPUT
{
float4 position : POSITION0;
float3 normalInView: TEXCOORD0;
float3 lightDirInView: TEXCOORD1;
float3 viewDirInView: TEXCOORD2;
};

VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;

Output.position = mul( Input.position, matWorldViewProjection );

Output.normalInView = mul( Input.normal, matWorldView);

Output.lightDirInView = lightPos - mul( Input.position, matWorldView);

float3 vPosition = mul( Input.position, matWorldView);

Output.viewDirInView = normalize(matView[3].xyz - vPosition);

return Output;
}

2) PixelShader

float4 ambientColor;

float4 diffuseColor;

float4 specularColor;

struct PS_INPUT
{
float3 normalInView: TEXCOORD0;
float3 lightDirInView: TEXCOORD1;
float3 viewDirInView: TEXCOORD2;
};

struct PS_OUTPUT
{
float4 color : COLOR0;
};

PS_OUTPUT ps_main( PS_INPUT In )
{
PS_OUTPUT Out;
In.normalInView = normalize(In.normalInView);
In.lightDirInView = normalize(In.lightDirInView);

float4 diffuse = max( 0, dot( In.normalInView, In.lightDirInView ));
diffuse = diffuse * diffuseColor;

float3 H = normalize(In.viewDirInView + In.lightDirInView);
float4 specular = specularColor * pow( max( 0, dot(H, In.normalInView)), 2 );

Out.color = ambientColor + diffuse + specular;

return Out;

}

                                               Blinn-Phong光照效果

posted on 2013-01-31 17:40  Just a Programer  阅读(7132)  评论(0编辑  收藏  举报