简单版本
效果如下
原理
使用法线贴图扭曲透明颜色贴图的uv值
Shader 代码1
Shader"PengLu/normal/iceTrans" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("BaseTex ", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_BumpAmt ("Distortion", range (0,2)) = 0.1
}
SubShader {
Tags { "Queue"="Transparent""RenderType"="Opaque" }
ZWrite off
CGPROGRAM
#pragma surface surfLambert nolightmap nodirlightmap alpha:blend
sampler2D _BumpMap;
sampler2D _MainTex;
float4 _Color;
float _BumpAmt;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
void surf (Input IN,inout SurfaceOutput o) {
fixed3 nor = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
fixed4 trans =tex2D(_MainTex,IN.uv_MainTex+nor.xy*_BumpAmt)*_Color;
o.Albedo = trans.rgb;
o.Alpha =trans.a;
o.Emission = trans;
}
ENDCG
}
FallBack"Transparent/VertexLit"
}
升级版本
效果如下
原理
使用grabtexture 截取屏幕并扭曲uv坐标,以达到透明折射的效果。 一些热浪扭曲效果也可用此shader引申出来
shader 代码2
Shader "PengLu/Custom/iceRefrationVF" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("BaseTex", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_BumpAmt ("Distortion", range (0,1)) = 0.12
}
Category {
// We must be transparent, so other objects are drawn before this one.
Tags { "Queue"="Transparent" "RenderType"="Opaque" }
zwrite off
SubShader {
// This pass grabs the screen behind the object into a texture.
// We can access the result in the next pass as _GrabTexture
GrabPass {
Name "BASE"
Tags { "LightMode" = "Always" }
}
// Main pass: Take the texture grabbed above and use the bumpmap to perturb it
// on to the screen
Pass {
Name "BASE"
Tags { "LightMode" = "Always" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord: TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
float4 uvgrab : TEXCOORD0;
float2 uvbump : TEXCOORD1;
float2 uvmain : TEXCOORD2;
UNITY_FOG_COORDS(3)
};
float _BumpAmt;
float4 _BumpMap_ST;
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
#else
float scale = 1.0;
#endif
o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
o.uvgrab.zw = o.vertex.zw;
//以上7行可以用o.uvgrab = ComputeGrabScreenPos(o.vertex);代替
o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
sampler2D _GrabTexture;
// float4 _GrabTexture_TexelSize;
float4 _Color;
sampler2D _BumpMap;
sampler2D _MainTex;
half4 frag (v2f i) : SV_Target
{
// calculate perturbed coordinates
half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg;
// we could optimize this by just reading the x & y without reconstructing the Z
float2 offset = bump * _BumpAmt ;
i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
half4 tint = tex2D(_MainTex, i.uvmain)*_Color*2;
col *= tint;
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
// ------------------------------------------------------------------
// Fallback for older cards and Unity non-Pro
SubShader {
Blend DstColor Zero
Pass {
Name "BASE"
SetTexture [_MainTex] { combine texture }
}
}
}
}
surface版本 shader代码:
Shader "PengLu/Custom/iceRefrationSurf" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("BaseTex", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_BumpAmt ("Distortion", range (0,1)) = 0.12
}
SubShader {
Tags { "Queue"="Transparent" "RenderType"="Opaque" }
ZWrite off
Lighting off
GrabPass {
Name "BASE"
Tags { "LightMode" = "Always" }
}
CGPROGRAM
#pragma surface surf Lambert nolightmap nodirlightmap
#pragma target 3.0
#pragma debug
float4 _Color;
sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _GrabTexture;
float _BumpAmt;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float4 screenPos;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed3 nor = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
fixed4 col = tex2D(_MainTex,IN.uv_MainTex);
float4 screenUV2 = IN.screenPos;
screenUV2.xy = screenUV2.xy / screenUV2.w;
screenUV2.xy += nor.xy * _BumpAmt;
fixed4 trans = tex2D(_GrabTexture,screenUV2.xy)*_Color;
trans*=col;
o.Albedo = trans.rgb;
o.Emission = trans.rgb;
;
}
ENDCG
}
FallBack "Transparent/VertexLit"
}
surface版本目前还有问题,在编辑视图里面结果是对的,但是再camera显示不正确。暂时能力不够没找到方法修改
|