So I need to do a multi pass, not sure if I’ve set up the shader correctly, trying to go off of blur/bloom, the thing I can’t work out is the taps part in those shader, are they completely necessary for multipass?
// AlanZucconi.com: http://www.alanzucconi.com/?p=4539
using UnityEngine;
using System.Collections;
//[ExecuteInEditMode]
public class ShaderBlit : MonoBehaviour
{
public Material material;
public RenderTexture texture;
private RenderTexture buffer;
public Texture initialTexture; // first texture
void Start ()
{
Graphics.Blit(initialTexture, texture);
buffer = new RenderTexture(texture.width, texture.height, texture.depth, texture.format);
}
// Postprocess the image
public void UpdateTexture()
{
Graphics.Blit(texture, buffer, material, 0);
Graphics.Blit(buffer, texture, material, 1);
}
// Updates regularly
private float lastUpdateTime = 0;
public float updateInterval = 0.1f; // s
public void Update ()
{
if (Time.time > lastUpdateTime + updateInterval)
{
UpdateTexture();
lastUpdateTime = Time.time;
}
}
}
Shader "Test/MultiPasstest"
{
Properties
{
_Color ("Color", Color) = (0,0,0,0)
_MainTex ("Color (RGB) Alpha (A)", 2D) = "white"
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float4 screenCoord : TEXCOORD1;
};
uniform float4 _Color;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = v.color;
o.uv = v.uv;
//o.screenCoord.xy = ComputeScreenPos(o.vertex);
return o;
}
sampler2D _MainTex;
sampler2D _Texture2;
float3 hash33(in float2 p)
{
float n = sin(dot(p, float2(41, 289)));
return frac(float3(2097152, 262144, 32768)*n);
}
// Serves no other purpose than to save having to write this out all the time. I could write a
// "define," but I'm pretty sure this'll be inlined.
float4 tx(in float2 p){ return tex2D(_MainTex, p); }
// Weighted blur function. Pretty standard.
float blur(in float2 p)
{
// Used to move to adjoining pixels. - uv + float2(-1, 1)*px, uv + float2(1, 0)*px, etc.
float3 e = float3(1, 0, -1);
float2 px = 1./512.;
// Weighted 3x3 blur, or a cheap and nasty Gaussian blur approximation.
float res = 0.0;
// Four corners. Those receive the least weight.
res += tx(p + e.xx*px ).x + tx(p + e.xz*px ).x + tx(p + e.zx*px ).x + tx(p + e.zz*px ).x;
// Four sides, which are given a little more weight.
res += (tx(p + e.xy*px ).x + tx(p + e.yx*px ).x + tx(p + e.yz*px ).x + tx(p + e.zy*px ).x)*2.;
// The center pixel, which we're giving the most weight to, as you'd expect.
res += tx(p + e.yy*px ).x*4.;
// Normalizing.
return res/16.;
}
fixed4 frag (v2f i) : SV_Target
{
float2 uv = i.uv; // Screen coordinates. Range: [0, 1]
float2 pw = 1./1.; // Relative pixel width. Used for neighboring pixels, etc.
// The blurred pixel. This is the result that's used in the "Image" tab. It's also reused
// in the next frame in the reaction diffusion process (see below).
float avgReactDiff = blur(uv);
// The noise value. Because the result is blurred, we can get away with plain old static noise.
// However, smooth noise, and various kinds of noise textures will work, too.
float3 noise = hash33(uv + float2(53, 43)*_Time.y)*.6 + .2;
// Used to move to adjoining pixels. - uv + float2(-1, 1)*px, uv + float2(1, 0)*px, etc.
float3 e = float3(1, 0, -1);
// Gradient epsilon value. The "1.5" figure was trial and error, but was based on the 3x3 blur radius.
float2 pwr = pw*1.5;
float2 lap = float2(tx(uv + e.xy*pwr).y - tx(uv - e.xy*pwr).y, tx(uv + e.yx*pwr).y - tx(uv - e.yx*pwr).y);//
// Add some diffusive expansion, scaled down to the order of a pixel width.
uv = uv + lap*pw*3.0;
// Stochastic decay. Ie: A differention equation, influenced by noise.
// You need the decay, otherwise things would keep increasing, which in this case means a white screen.
float newReactDiff = tx(uv).x + (noise.z - 0.5)*0.0025 - 0.002;
// Reaction-diffusion.
newReactDiff += dot(tx(uv + (noise.xy-0.5)*pw).xy, float2(1, -1))*0.145;
float iFrame = _Time.y;
// Storing the reaction diffusion value in the X channel, and avgReactDiff (the blurred pixel value)
// in the Y channel. However, for the first few frames, we add some noise. Normally, one frame would
// be enough, but for some weird reason, it doesn't always get stored on the very first frame.
if(iFrame>0.2) _Color.xy = clamp(float2(newReactDiff, avgReactDiff/.98), 0., 1.);
else _Color = (noise, 1.);
return _Color;
}
fixed4 frag2 (v2f i) : SV_Target
{
// The screen coordinates.
float2 uv = i.uv;
// Read in the blurred pixel value. There's no rule that says you can't read in the
// value in the "X" channel, but blurred stuff is easier to bump, that's all.
float c = 1. - tex2D(_MainTex, uv).y;
// Reading in the same at a slightly offsetted position. The difference between
// "c2" and "c" is used to provide the highlighting.
float c2 = 1. - tex2D(_MainTex, uv + .5/1.0).y;
// Color the pixel by mixing two colors in a sinusoidal kind of pattern.
//
float pattern = -cos(uv.x*0.75*3.14159-0.9)*cos(uv.y*1.5*3.14159-0.75)*0.5 + 0.5;
//
// Blue and gold, for an abstract sky over a... wheat field look. Very artsy. :)
float3 col = float3(c*1.5, pow(c, 2.25), pow(c, 6.));
col = lerp(col, col.zyx, clamp(pattern-.2, 0., 1.) );
// Extra color variations.
//float3 col = mix(float3(c*1.2, pow(c, 8.), pow(c, 2.)), float3(c*1.3, pow(c, 2.), pow(c, 10.)), pattern );
//float3 col = mix(float3(c*1.3, c*c, pow(c, 10.)), float3(c*c*c, c*sqrt(c), c), pattern );
// Adding the highlighting. Not as nice as bump mapping, but still pretty effective.
col += float3(.6, .85, 1.)*max(c2*c2 - c*c, 0.)*12.;
// Apply a vignette and increase the brightness for that fake spotlight effect.
col *= pow( 16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y) , .125)*1.15;
// Fade in for the first few seconds.
col *= smoothstep(0., 1., _Time.y/2.);
// Done.
_Color = float4(min(col, 1.), 1.);
return _Color;
}
ENDCG
SubShader{
ZTest Always Cull Off ZWrite Off
Fog{ Mode off }
//Pass 0
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
//Pass 1
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag2
ENDCG
}
}
}