前言:本篇博客只是一个简单的了解热浪扭曲火焰的例子,主要是当做笔记使用。
设计流程:如下所示:
1.新建一个场景,里面包含一个地板floor,一个墙面wall和一个火焰例子fire(自带粒子系统中的火焰)。如图所示:
2.新建一个fire shader和material并赋给场景中的fire对象。fire shader使用的纹理跟粒子系统中自带的纹理一样。如图所示:
3.fire shader设计要点:
核心操作如下所示:
.>使用GrabPass来抓取非透明物体渲染的纹理。这里就是地面和墙面所渲染出来的纹理。
.>在一个Pass中将火焰纹理的坐标转换成投影纹理映射采样坐标。并将火焰的颜色分量中的r(最好用a)来作为采样坐标扭曲系数,在火焰中心点时扭曲系数越大,火焰周边时扭曲系数越小。然后使用扭曲系数来叠加到投影纹理映射采样坐标中,用这个采样坐标对GrabPass抓取的纹理进行采样,从而得到热浪扭曲的效果。
.>在一个Pass中对火焰纹理进行采样得到火焰颜色。然后使用blend one one来对另外Pass中得到的热浪扭曲颜色进行叠加,从而得到热浪扭曲火焰效果。
核心代码如下所示:
Shader "Unlit/FireShade"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" "queue"="transparent" }
LOD 100
// 抓取通道,用来获取当前不透明物体的纹理
GrabPass
{
}
// 对抓取的纹理进行扭曲
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
// 投影纹理映射采样坐标
float4 screenPos : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _GrabTexture;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// 经过模型空间-》世界空间-》视角空间-》齐次裁剪空间-》投影纹理缩放矩阵变换后的投影纹理映射采样坐标
o.screenPos = ComputeGrabScreenPos(o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// 对火焰纹理进行采样并用r值(火焰中心值越大,两侧值越小)来改变投影纹理采样坐标,从而达到扭曲效果。
fixed4 col = tex2D(_MainTex, i.uv);
i.screenPos.xy += col.r * 0.01;
// 投影纹理映射采样坐标经过透视除法后进行投影纹理采样
fixed4 bg = tex2Dproj(_GrabTexture, i.screenPos);
return bg;
}
ENDCG
}
// 对火焰纹理采样并和上面的扭曲背景效果叠加
Pass
{
blend one one
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// 对火焰纹理进行采样
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
4.运行效果如下所示: