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 );
      
}





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

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值