Unity: можно ли использовать 2 прохода подряд? - PullRequest
0 голосов
/ 05 октября 2018

У меня есть шейдер с несколькими проходами внутри, 2 из которых - контурный проход и проход размытия.Я пытаюсь создать контур, а затем размыть его.Как заставить проход размытия принять на выходе прохода контура размытие?

Обход плана:

Pass{
        Name "OUTLINE"
        Cull Off
        ZWrite Off
        ZTest Always
        Blend SrcAlpha OneMinusSrcAlpha
    CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile_fog

    fixed4 frag(v2f IN) : SV_Target
    {
        fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;

        if (c.a > _Cutoff) {
            float totalAlpha = 1.0;

            [unroll(16)]
            for (int i = 1; i < _OutlineSize + 1; i++) {
                fixed4 pixelUp = tex2D(_MainTex, IN.texcoord + fixed2(0, i * _MainTex_TexelSize.y));
                fixed4 pixelDown = tex2D(_MainTex, IN.texcoord - fixed2(0, i *  _MainTex_TexelSize.y));
                fixed4 pixelRight = tex2D(_MainTex, IN.texcoord + fixed2(i * _MainTex_TexelSize.x, 0));
                fixed4 pixelLeft = tex2D(_MainTex, IN.texcoord - fixed2(i * _MainTex_TexelSize.x, 0));

                totalAlpha = totalAlpha * pixelUp.a * pixelDown.a * pixelRight.a * pixelLeft.a;
            }

            if (totalAlpha == 0) {
                c.rgba = fixed4(0.4, 1, 1, 1);
            }
            else
                c.rgba = fixed4(0.5, 0.5, 0.5, .5);
        }

        c.rgb *= c.a;
        return c;
    }

    ENDCG
    }

Проход размытия:

Pass{
        Name "BLUR"
        Cull Off
        ZWrite Off
        ZTest Always
        Blend SrcAlpha OneMinusSrcAlpha
        CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile_fog

        fixed4 frag(v2f IN) : SV_Target
    {
        fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;

        if (c.a > _Cutoff) {
            fixed4 pixelUp = tex2D(_MainTex, IN.texcoord + fixed2(0, _MainTex_TexelSize.y));
            fixed4 pixelDown = tex2D(_MainTex, IN.texcoord - fixed2(0,  _MainTex_TexelSize.y));
            fixed4 pixelRight = tex2D(_MainTex, IN.texcoord + fixed2(_MainTex_TexelSize.x, 0));
            fixed4 pixelLeft = tex2D(_MainTex, IN.texcoord - fixed2(_MainTex_TexelSize.x, 0));
            fixed4 pixelUp2 = tex2D(_MainTex, IN.texcoord + fixed2(0, 2 * _MainTex_TexelSize.y));
            fixed4 pixelDown2 = tex2D(_MainTex, IN.texcoord - fixed2(0, 2 * _MainTex_TexelSize.y));
            fixed4 pixelRight2 = tex2D(_MainTex, IN.texcoord + fixed2(2 * _MainTex_TexelSize.x, 0));
            fixed4 pixelLeft2 = tex2D(_MainTex, IN.texcoord - fixed2(2 * _MainTex_TexelSize.x, 0));
            fixed4 pixelUp3 = tex2D(_MainTex, IN.texcoord + fixed2(0, 3 * _MainTex_TexelSize.y));
            fixed4 pixelDown3 = tex2D(_MainTex, IN.texcoord - fixed2(0, 3 * _MainTex_TexelSize.y));
            fixed4 pixelRight3 = tex2D(_MainTex, IN.texcoord + fixed2(3 * _MainTex_TexelSize.x, 0));
            fixed4 pixelLeft3 = tex2D(_MainTex, IN.texcoord - fixed2(3 * _MainTex_TexelSize.x, 0));

            c = c * 0.18
                + 0.15 * (pixelUp + pixelDown + pixelRight + pixelLeft)
                + 0.12 * (pixelUp2 + pixelDown2 + pixelRight2 + pixelLeft2);
                + 0.09 * (pixelUp3 + pixelDown3 + pixelRight3 + pixelLeft3);
        }

        c.rgb *= c.a;
        return c;
    }

        ENDCG
    }

Яновичок в шейдерах, поэтому, если есть какие-либо советы, будет оценен

1 Ответ

0 голосов
/ 05 октября 2018

Используя Grab pass , вы можете взять сгенерированный на данный момент экран и сэмплировать его за другой проход.

В вашем случае поместите его после прохода контура и выберите образец полученной текстуры в проходе размытия вместо необработанной текстуры.

Pass{
    // ...
    // no change
    // ...
}

GrabPass { "_GrabTexture" }        

Pass{ 
    // Note the changes from calling tex2D with _MainTex to _GrabTexture, 
    // matching the string in the GrabPass directive above 

    // ...
    // use a vertex shader to get the uvs of the screen grab

    struct v2f {
        float4 grabPos : TEXCOORD0;
        float4 pos : SV_POSITION;
    };

    v2f vert(appdata_base v) {
        v2f o;
        // use UnityObjectToClipPos from UnityCG.cginc to calculate 
        // the clip-space of the vertex
        o.pos = UnityObjectToClipPos(v.vertex);
        // use ComputeGrabScreenPos function from UnityCG.cginc
        // to get the correct texture coordinate
        o.grabPos = ComputeGrabScreenPos(o.pos);
        return o;
    }

    // Note the changes from calling tex2D with _MainTex to _GrabTexture, 
    // matching the string in the GrabPass directive above 
    // as well as IN.grabPos instead of IN.texcoord
    // and tex2Dproj instead of tex2D

    fixed4 frag(v2f IN) : SV_Target {
        fixed4 c = tex2Dproj(_GrabTexture, IN.grabPos) * IN.color; 

        if (c.a > _Cutoff) {
            fixed4 pixelUp = tex2Dproj(_GrabTexture, IN.grabPos+ fixed2(0, _MainTex_TexelSize.y));
            fixed4 pixelDown = tex2Dproj(_GrabTexture, IN.grabPos - fixed2(0,  _MainTex_TexelSize.y));
            fixed4 pixelRight = tex2Dproj(_GrabTexture, IN.texcoord + fixed2(_MainTex_TexelSize.x, 0));
            fixed4 pixelLeft = tex2Dproj(_GrabTexture, IN.texcoord - fixed2(_MainTex_TexelSize.x, 0));
            fixed4 pixelUp2 = tex2Dproj(_GrabTexture, IN.texcoord + fixed2(0, 2 * _MainTex_TexelSize.y));
            fixed4 pixelDown2 = tex2Dproj(_GrabTexture, IN.texcoord - fixed2(0, 2 * _MainTex_TexelSize.y));
            fixed4 pixelRight2 = tex2Dproj(_GrabTexture, IN.texcoord + fixed2(2 * _MainTex_TexelSize.x, 0));
            fixed4 pixelLeft2 = tex2Dproj(_GrabTexture, IN.texcoord - fixed2(2 * _MainTex_TexelSize.x, 0));
            fixed4 pixelUp3 = tex2Dproj(_GrabTexture, IN.texcoord + fixed2(0, 3 * _MainTex_TexelSize.y));
            fixed4 pixelDown3 = tex2Dproj(_GrabTexture, IN.texcoord - fixed2(0, 3 * _MainTex_TexelSize.y));
            fixed4 pixelRight3 = tex2Dproj(_GrabTexture, IN.texcoord + fixed2(3 * _MainTex_TexelSize.x, 0));
            fixed4 pixelLeft3 = tex2Dproj(_GrabTexture, IN.texcoord - fixed2(3 * _MainTex_TexelSize.x, 0));

            c = c * 0.18
                + 0.15 * (pixelUp + pixelDown + pixelRight + pixelLeft)
                + 0.12 * (pixelUp2 + pixelDown2 + pixelRight2 + pixelLeft2);
                + 0.09 * (pixelUp3 + pixelDown3 + pixelRight3 + pixelLeft3);
        }

        c.rgb *= c.a;
        return c;
    }

        ENDCG
    }
...