天天看點

shader鏡面反射(Reflection)這裡用DXUT 實作的一個反射的Demo(下載下傳位址) 鏡面反射:

這裡用DXUT 實作的一個反射的Demo(下載下傳位址)

鏡面反射:

要實作場景中類似鏡面反射的場景,是一種很美妙的事,列如水中的倒影,玻璃上面的反射.下面我們來實作這種功能.我們來看一下實作的效果.

shader鏡面反射(Reflection)這裡用DXUT 實作的一個反射的Demo(下載下傳位址) 鏡面反射:

實作步驟:

需要先用一張立方體環境貼圖,實作環境的顔色,.渲染立方體環境.這個在這裡就不啰嗦了.

我們重點是實作對環境的反射.

shader鏡面反射(Reflection)這裡用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 );
      
}


           
shader鏡面反射(Reflection)這裡用DXUT 實作的一個反射的Demo(下載下傳位址) 鏡面反射:

這裡用DXUT 實作的一個反射的Demo(下載下傳位址)

繼續閱讀