Shaders for Game Programmers and Artists(4) - 热雾效果

一、原理

先看下面的图



产生的原理及其就是折射。
深入探究的话,可以去搜搜波粒二象性,斯涅尔定律等等。
当太阳照射地面的时候,靠近地面的空气会变得很热,热空气比较轻会往上走,冷的空气会往下沉。冷热空气由于有着不同的密度和折射率,就产生了折射现象。
下面是折射的示意图


这种特效可以用于喷气背包或者火箭升空时候火焰处空气扭曲的效果,也可以用于其他介质比如水或者刀光的处理。


二、动手

首先给场景添加一个天空球,Steam mapping设置如下

一定要记得设置这个!
一定要记得设置这个!
一定要记得设置这个!

添加一个球的模型,添加一个Cubemap
RenderState中设置



Vs中让球围绕在视角的周围

float4x4 view_proj_matrix;
float4 view_position;
struct VS_OUTPUT 
{
   float4 Pos: POSITION;
   float3 dir: TEXCOORD0;
};

VS_OUTPUT vs_main(float4 Pos: POSITION)
{
   VS_OUTPUT Out;

   // Center environment around camera
   Out.Pos = mul(view_proj_matrix, float4(Pos.xyz + view_position, 1));
   Out.dir = Pos.xyz;

   return Out;
}

PS中绘制cubemap

sampler Environment;
float4 ps_main(float3 dir: TEXCOORD0) : COLOR 
{
   // Sample and output the environment map color
   return texCUBE(Environment, dir);
}


模型就按往常那样绘制就可以了。

先把天空盒和模型一起绘制到一张rt上。


再创建一个rt来存一份前面渲染结果的拷贝,用于后面的Heat_Impostor pass.
创建一个专门用于拷贝的pass

在接下来的pass中,进行扭曲操作


这里引用了一张3d噪声贴图,把它加到工程中来。

通过对3D噪声的采样,得到一个纹理坐标的偏移值,


这个3D噪声贴图,其实就是Distortion map


distortion map
Before sampling the actual render target, you will sample the distortion map. The values contained within this map are not actual pixels, but offsets, which can be used to offset how the render target itself is read.



具体采样的代码如下

float OffsetScale;
float time_0_1;
sampler Texture0;
sampler Texture1;
float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR 
{
   // Read and scale the distortion offsets
   float2 offset = tex3D(Texture1,float3(8*texCoord.x,8*texCoord.y,0)).xy;
   offset = ((offset*2.0)-1.0)*OffsetScale;
   
   return tex2D(Texture0,texCoord+offset);
}

3d纹理采样的坐标乘以8,目的是
This is merely to allow a better noisiness of the texture by repeating the distortion map multiple times throughout the screen

添加了一个OffsetScale作为偏移量的缩放,可以控制扭曲的程度。


最后present出来就好了




如果想加上扭曲的动态效果的话,添加一个时间变量就可以了


float OffsetScale;
float time_0_1;
sampler Texture0;
sampler Texture1;
float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR 
{
   // Read and scale the distortion offsets
   float2 offset = tex3D(Texture1,float3(8*texCoord.x,8*texCoord.y + 2* time_0_1,time_0_1)).xy;
   offset = ((offset*2.0)-1.0)*OffsetScale;
   
   return tex2D(Texture0,texCoord+offset);
}


这样就有动态的热雾效果了!


三、冒热气的水壶

上面的效果是整个屏幕的效果,但是通常这种热雾效果只出现在屏幕的一部分,比如喷气背包的火焰,比如灼热的路面等,下面就来看下面冒热气的水壶的例子。

这里实现了一个粒子系统,在绘制粒子系统的时候,

在PS中采样Distortion map,然后采样之前渲染出来的rt得到了最终的结果。

float OffsetScale;
float particleShape;
sampler RT;
sampler Distortion;
float4 main(float3 texCoord: TEXCOORD0,float2 texCoord2: TEXCOORD1) : COLOR 
{
   float2 offset = tex3D(Distortion,
                   float3(texCoord2.xy,0)).xy;
   offset = ((offset*2.0)-1.0)*OffsetScale;
   
   float fade = pow(dot(texCoord2, texCoord2), particleShape);
   return float4(tex2D(RT, texCoord.xy+offset).xyz,(1 - fade));
}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值