3
\$\begingroup\$

I have a shader which uses multiple passes to determine the thickness of an object at each point. I want to use this thickness value in order to sample from a texture, which will determine the color of the screen at that point. However, since the calculation is performed in two passes, I don't have any way to access the one value which results at the end, which is what I would be using to index the uv for the texture. Thanks for any help in advance!

{
Properties
{
    _MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
    Pass
    {
        Cull Back ZWrite On ZTest Always
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
        };

        struct v2f
        {
            float2 depth : DEPTH;
            float4 vertex : SV_POSITION;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.depth = -UnityObjectToViewPos(v.vertex).z * 200 * _ProjectionParams.w;
            return o;
        }

        sampler2D _MainTex;

        fixed4 frag (v2f i) : SV_Target
        {
            float c=1-i.depth;
            fixed4 col = fixed4(c,c,c,1);
            return col;
        }
        ENDCG
    }
    Pass
    {
        Cull Front ZWrite On ZTest Always
        BlendOp RevSub
        Blend One One
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
        };

        struct v2f
        {
            float2 depth : DEPTH;
            float4 vertex : SV_POSITION;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.depth = -UnityObjectToViewPos(v.vertex).z * 200* _ProjectionParams.w;
            return o;
        }

        sampler2D _MainTex;

        fixed4 frag (v2f i) : SV_Target
        {
            float c = 1-i.depth;
            //fixed4 col = tex2D(_MainTex,c.xx);
            fixed4 col = fixed4(c,c,c,1);
            return col;
        }
        ENDCG
    }
}
}
\$\endgroup\$
2
  • \$\begingroup\$ Usually you'd write your intermediate result to a RenderTexture and sample that. Have you tried doing it this way, or is that not an option for your situation? \$\endgroup\$
    – DMGregory
    Aug 21, 2017 at 1:33
  • 1
    \$\begingroup\$ I haven't tried that-- What would I use in order to write to the RenderTexture instead of _MainTex? \$\endgroup\$ Aug 21, 2017 at 1:47

1 Answer 1

7
\$\begingroup\$

Use a grab pass

{
Properties
{
    _MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
    Pass
    {
        Cull Back ZWrite On ZTest Always
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
        };

        struct v2f
        {
            float2 depth : DEPTH;
            float4 vertex : SV_POSITION;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.depth = -UnityObjectToViewPos(v.vertex).z * 200 * _ProjectionParams.w;
            return o;
        }

        sampler2D _MainTex;

        fixed4 frag (v2f i) : SV_Target
        {
            float c=1-i.depth;
            fixed4 col = fixed4(c,c,c,1);
            return col;
        }
        ENDCG
    }

    GrabPass { "_GrabTexture" }        

    Pass
    {
        Cull Front ZWrite On ZTest Always
        BlendOp RevSub
        Blend One One
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
        };

        struct v2f
        {
            float2 depth : DEPTH;
            float4 vertex : SV_POSITION;
            float4 grabUv : TEXCOORD0;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.depth = -UnityObjectToViewPos(v.vertex).z * 200* _ProjectionParams.w;
            o.grabUv = ComputeGrabScreenPos (o.vertex);
            return o;
        }

        sampler2D _MainTex;
        sampler2D _GrabTexture;

        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 lastPassColor = tex2Dproj(_GrabTexture, i.grabUv);
            float c = 1-i.depth;
            fixed4 col = tex2D(_MainTex,c.xx);
            //fixed4 col = fixed4(c,c,c,1);
            return col;
        }
        ENDCG
    }
}
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .