天天看点

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(下载地址)

继续阅读