Is there any way to do multiple passes on a texture / in a fragment shader?
Is there any way to do multiple passes in a fragment shader? I need to transform the texture in the first step and then in the second step modify parts were affected by the first pass. Is there any way to do this with a single shader? I wrote an example one how I would like to to it but the first pass seems to be fully ignored:
Shader "Test/FragmentShaderWithMemory" {
Properties {
_MainTex ("MainTexture", 2D) = "white" {}
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
float3 frag(v2f_img i) : COLOR {
float3 pixelColor = tex2D(_MainTex, i.uv);
// the red channel to 0 as a test:
pixelColor.x = 0;
return pixelColor;
}
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
float3 frag(v2f_img i) : COLOR {
float3 pixelColor = tex2D(_MainTex, i.uv);
// all pixels should now have red to 0, test by setting all green channels to 1:
if (pixelColor.x==0) pixelColor.y = 1;
return pixelColor;
}
ENDCG
}
}
}
Answer by Namey5 · Apr 21, 2018 at 10:46 PM
You can actually use the GrabPass {} function as a bit of a hack here to pass information between passes in a shader. In your case, try the following:
Shader "Test/FragmentShaderWithMemory" {
Properties {
_MainTex ("MainTexture", 2D) = "white" {}
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
float3 frag(v2f_img i) : COLOR {
float3 pixelColor = tex2D(_MainTex, i.uv);
// the red channel to 0 as a test:
pixelColor.x = 0;
return pixelColor;
}
ENDCG
}
GrabPass { "_MainTex2" }
Pass {
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex2;
float3 frag(v2f_img i) : COLOR {
i.uv.y = 1 - i.uv.y; //You might have to do this to invert the grab pass texture in some cases where it's flipped
float3 pixelColor = tex2D(_MainTex2, i.uv);
// all pixels should now have red to 0, test by setting all green channels to 1:
if (pixelColor.x==0) pixelColor.y = 1;
return pixelColor;
}
ENDCG
}
}
}
Thanks for the tip with GrabPass, now that I knew what to search for I found UsePass ( https://docs.unity3d.com/$$anonymous$$anual/SL-UsePass.html ) as well, does it do the same as GrabPass just with separate shader files? or might it be something I should try as well? Or is UsePass just a way to put separate passes into separate files?
UsePass won't work. It's simply a way of adding references to passes to shaders without having to write them out fully.