shader镜面反射(Reflection)

时间:2022-01-09 14:49:07

这里用DXUT 实现的一个反射的Demo(下载地址)


镜面反射:

要实现场景中类似镜面反射的场景,是一种很美妙的事,列如水中的倒影,玻璃上面的反射.下面我们来实现这种功能.我们来看一下实现的效果.
shader镜面反射(Reflection)

实现步骤:

需要先用一张立方体环境贴图,实现环境的颜色,.渲染立方体环境.这个在这里就不啰嗦了.
我们重点是实现对环境的反射.
shader镜面反射(Reflection)
以上的现象遵循物理反射定律,反射角等于入射角,即 角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(下载地址)