2
\$\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 '17 at 1:33
  • \$\begingroup\$ I haven't tried that-- What would I use in order to write to the RenderTexture instead of _MainTex? \$\endgroup\$ Aug 21 '17 at 1:47
5
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.