What we going to do here:
DOWNLOAD:
https://dl.dropboxusercontent.com/u/106482752/Dvornik-Unity-Distortion.zip
Root tutorial: http://kostiantyn-dvornik.blogspot.com/2014/07/anoxemia-unity-2d-tutorial.html
If you ever want to create cool effects like hot air waving or thick glass refraction or some underwater streams you will came to Detonator package and HeatDistort shader.But as for me it looks very complicated, so write my own and use it well with latest Unity 2D system.
NOTE: it works only with Unity Pro and Deffered lighting on. It works the same way how Detonator'a works. It tooks image and project it correctly on a plane with texture distortion.
We will split tutorial into 2 steps.
1.Explain shader
2. How to use it.
1.
Lets take a look at the shader:
Shader "Dvornik/Distort" {
Properties {
_Refraction ("Refraction", Range (0.00, 100.0)) = 1.0
_DistortTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Transparent" "Queue"="Overlay" }
LOD 100
GrabPass
{
}
CGPROGRAM
#pragma surface surf NoLighting
#pragma vertex vert
fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten){
fixed4 c;
c.rgb = s.Albedo;
c.a = s.Alpha;
return c;
}
sampler2D _GrabTexture : register(s0);
sampler2D _DistortTex : register(s2);
float _Refraction;
float4 _GrabTexture_TexelSize;
struct Input {
float2 uv_DistortTex;
float3 color;
float3 worldRefl;
float4 screenPos;
INTERNAL_DATA
};
void vert (inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input,o);
o.color = v.color;
}
void surf (Input IN, inout SurfaceOutput o) {
float3 distort = tex2D(_DistortTex, IN.uv_DistortTex) * float3(IN.color.r,IN.color.g,IN.color.b );
float2 offset = distort * _Refraction * _GrabTexture_TexelSize.xy;
IN.screenPos.xy = offset * IN.screenPos.z + IN.screenPos.xy;
float4 refrColor = tex2Dproj(_GrabTexture, IN.screenPos);
o.Alpha = refrColor.a;
o.Emission = refrColor.rgb;
}
ENDCG
}
}
We have just 2 properties. It is
_Refraction -amount of distortion
_DistortText - texture according to what we gonna distort our environment. You can use any colored texture. To make distortion. But in fact only Red and Green channels are working as distortion vector.
Tags { "RenderType"="Transparent" "Queue"="Overlay" } - We set Queue to Overlay because we want to render this effect after everything.
#pragma surface surf NoLighting
#pragma vertex vert
We used custom NoLigthing model and custom vertex shader to have deal with vertex color that used in particle system. There is a little chunk, cuz we write only Emission to have absolutely No Lighting shader.
float3 distort = tex2D(_DistortTex, IN.uv_DistortTex) * float3(IN.color.r,IN.color.g,IN.color.b );
float2 offset = distort * _Refraction * _GrabTexture_TexelSize.xy;
IN.screenPos.xy = offset * IN.screenPos.z + IN.screenPos.xy;
float4 refrColor = tex2Dproj(_GrabTexture, IN.screenPos);
Here we read distort texture, calculate offset of the screen and project on the model correctly. That's it.
2.
Create a simple material and apply that shader. Next if you use particle system apply particle render order script to that. Other way some object will be rendered after distortion so it will looks weird. You can use particle Color or Color Over LifeTime to make distortion more/less. I often setup it thats way:
to make distortion fade in and fade out. Thats probabbly all that you need to know about.
Know bugs:
1.
Add particle order script to PS and set order to bigger then foreground sprite.
Effect is not working with orthographic camera
2. To much distortion on large distance to camera
How to resolve: add script that decreasing material property distortion with distance to camera.
No comments:
Post a Comment