Shader系列(3):Blinn-Phong光照模型


     圖形學界大牛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光照效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM