Shader "CrispyPin/diffuse" { Properties { [NoScaleOffset] _LastFrame ("Render texture", 2D) = "white" {} [NoScaleOffset] _Noise ("Noise", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #define WIDTH 256 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; texture2D _LastFrame; sampler2D _Noise; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } float3 modify(float2 uv, float3 source) { float3 rand = tex2D(_Noise, uv + _Time.yz + source); float3 q = 0.01 * rand; return source - q; } float3 source_pixel(uint2 p, float2 uv, float2 rand_offset) { const uint dir = tex2D(_Noise, uv + _Time.xy + rand_offset).r * (10.0 + sin(_Time.y*10) * 6.); if (dir == 0) { p.x += 1; } else if (dir == 1) { p.y += 1; } else if (dir == 2) { p.x -= 1; } else if (dir == 3) { p.y -= 1; } else { return modify(uv, _LastFrame[p]); // return _LastFrame[p]; } return _LastFrame[p]; } float4 frag (v2f i) : SV_Target { if(_ProjectionParams.z > 1) discard; const uint2 p = i.uv * WIDTH; float3 s = modify(i.uv, _LastFrame[p]); float red = s.r; float green = s.g; float blue = s.b; const float epsilon = 0.1; if (red <= epsilon) { red = source_pixel(p, i.uv, float2(0.34, 0.89)).r; } if (green <= epsilon) { green = source_pixel(p, i.uv, float2(0.43, 0.19)).g; } if (blue <= epsilon) { blue = source_pixel(p, i.uv, float2(0.03, 0.39)).b; } return float4(red, green, blue, 1); } ENDCG } } }