Unity 热浪扭曲Shader的实现,参考http://blog.csdn.net/qq18052887/article/details/50457680这位博主大大的实现方式。
首先介绍网上常见的使用GrabPass的实现方式来实现,主要思路是通过将GrabPass截取的图片根据噪声图片来偏移截图的uv,从而实现图片的扭曲。
下面贴出代码:
Shader "Hidden/ImageGlass"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_NoiseTex("Noise Texture",2D) = "white"{}
_MaskTex("Mask Texture",2D) = "white"{}
_HeatTime ("Heat Time",range(0,1.5)) = 1
_HeatForce ("Heat Force",range(0,1.0)) = 0.1
}
SubShader
{
Tags {"Queue" = "Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
AlphaTest Greater 0.1
Cull Off
ZWrite Off
Lighting Off
GrabPass{"_RefractionTex"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _NoiseTex;
float4 _NoiseTex_ST;
float _HeatTime;
float _HeatForce;
sampler2D _RefractionTex;
sampler2D _MaskTex;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 uvgrab : TEXCOORD1;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv,_MainTex);
o.uvgrab = ComputeGrabScreenPos(o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
/*===============================================================
将uv坐标偏移
================================================================*/
half4 offestcol1 = tex2D(_NoiseTex,i.uv + _Time.xz * _HeatTime);
half4 offestcol2 = tex2D(_NoiseTex,i.uv - _Time.yx * _HeatTime);
i.uvgrab.x += ((offestcol1.r + offestcol2.r) - 1) * _HeatForce;
i.uvgrab.y += ((offestcol1.g + offestcol2.g) - 1) * _HeatForce;
/*===========================================================*/
half4 col = tex2Dproj(_RefractionTex,UNITY_PROJ_COORD(i.uvgrab));
half4 maskcol = tex2D(_MaskTex, i.uv);
col.a = maskcol.a;
half4 tint = tex2D(_MainTex,i.uv);
return col * tint;
}
ENDCG
}
}
}
第二种方法
因为GrabPass在移动平台上消耗很大,所以参考博主的文章,其实是可以在渲染后直接对相机图片进行扭曲的,效率就上来了。
Shader "Hidden/ImageGlass"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_NoiseTex ("Noise Texture (RG)", 2D) = "white" {}
_MaskTex ("Mask Texture", 2D) = "white" {}
_HeatTime ("Heat Time", range (0,1.5)) = 1
_HeatForce ("Heat Force", range (0,0.1)) = 0.1
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
float _HeatForce;
float _HeatTime;
uniform sampler2D _MainTex;
uniform sampler2D _NoiseTex;
uniform sampler2D _MaskTex;
fixed4 frag(v2f_img i) : COLOR
{
fixed mask = tex2D(_MaskTex, i.uv).a;
// 扭曲效果
half4 offsetColor1 = tex2D(_NoiseTex, i.uv + _Time.xz*_HeatTime);
half4 offsetColor2 = tex2D(_NoiseTex, i.uv - _Time.yx*_HeatTime);
i.uv.x += ((offsetColor1.r + offsetColor2.r) - 1) * _HeatForce * mask;
i.uv.y += ((offsetColor1.g + offsetColor2.g) - 1) * _HeatForce * mask;
fixed4 renderTex = tex2D(_MainTex, i.uv);
return renderTex;
}
ENDCG
}
}
FallBack off
}
这个还要配合屏幕后处理脚本使用。