這裡用DXUT 實作的一個反射的Demo(下載下傳位址)
鏡面反射:
要實作場景中類似鏡面反射的場景,是一種很美妙的事,列如水中的倒影,玻璃上面的反射.下面我們來實作這種功能.我們來看一下實作的效果.
實作步驟:
需要先用一張立方體環境貼圖,實作環境的顔色,.渲染立方體環境.這個在這裡就不啰嗦了.
我們重點是實作對環境的反射.
以上的現象遵循實體反射定律,反射角等于入射角,即 角a = 角b
在HLSL 中有refect 反射函數 傳回入射光線i對表面法線n的反射光線。
在反射物體中,通過使用每個像素點上的反射向量來索引到立方體紋理上的像素,就能近似模拟反射效果了.
Pixel Shader 裡面的代碼
float3 vLight;
float AmbientIntensity;
float DiffuseIntensity;
float SpecularIntensity;
float4 AmbientColor;
float4 DiffuseColor;
float4 SpecularColor;
float SpecularPow;
samplerCUBE Environment;
struct PS_INPUT
{
float3 Normal : TEXCOORD0;
float3 Eye : TEXCOORD1;
};
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float3 light = normalize(vLight);
float3 eye = normalize(Input.Eye);
float3 normal = normalize(Input.Normal);
float ndl = saturate(dot(light, normal));
//光線的反射方向
float3 r = normalize(reflect(-light, normal));
float rdv = pow(saturate(dot(r, eye)), SpecularPow);
//環境貼圖
//這兩行主要功能
float3 reflectEye = reflect(-eye, normal);
float4 reflectColor = texCUBE(Environment, reflectEye);
//光照方程
float4 color = AmbientColor * AmbientIntensity + DiffuseColor * DiffuseIntensity * ndl + SpecularColor * SpecularIntensity * rdv;
return reflectColor * color;
}
主要代碼就是
float3 reflectEye = reflect(-eye, normal);
float4 reflectColor = texCUBE(Environment, reflectEye);
實作的原理是反射物體的效果檔案不再是取自身的紋理,而是取環境立方體的紋理了.
同時我們看一下Vertex Shader 裡面的代碼吧,這個和以前的沒有什麼差別,姑且看看吧
float4x4 matWorldViewProjection;
float4x4 matWorldInverseTranspose;
float4x4 matWorld;
float4 vViewPosition;
struct VS_INPUT
{
float4 Position : POSITION0;
float4 Normal : NORMAL0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float3 Normal : TEXCOORD0;
float3 Eye : TEXCOORD1;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul( Input.Position, matWorldViewProjection );
//法線變換要用世界矩陣逆矩陣的轉置矩陣,但除了做非等比例的縮放時,直接用世界矩陣也可以
Output.Normal = mul ( Input.Normal, matWorldInverseTranspose );
//視線
Output.Eye = vViewPosition - mul(Input.Position, matWorld);
return( Output );
}
這裡用DXUT 實作的一個反射的Demo(下載下傳位址)