先看下面的图
产生的原理及其就是折射。
深入探究的话,可以去搜搜波粒二象性,斯涅尔定律等等。
当太阳照射地面的时候,靠近地面的空气会变得很热,热空气比较轻会往上走,冷的空气会往下沉。冷热空气由于有着不同的密度和折射率,就产生了折射现象。
下面是折射的示意图
这种特效可以用于喷气背包或者火箭升空时候火焰处空气扭曲的效果,也可以用于其他介质比如水或者刀光的处理。
首先给场景添加一个天空球,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; }
sampler Environment; float4 ps_main(float3 dir: TEXCOORD0) : COLOR { // Sample and output the environment map color return texCUBE(Environment, dir); }
在接下来的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); }
如果想加上扭曲的动态效果的话,添加一个时间变量就可以了
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)); }