【问题标题】:Unity: Is it possible to use 2 passes consecutively?Unity:可以连续使用2个pass吗?
【发布时间】:2018-10-05 02:36:27
【问题描述】:

我有一个着色器,里面有多个通道,其中 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
    }

我是着色器的新手,所以如果有任何建议将不胜感激。

【问题讨论】:

    标签: unity3d graphics shader multipass


    【解决方案1】:

    使用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
        }
    

    【讨论】:

      猜你喜欢
      • 2021-10-25
      • 2021-10-02
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 2021-06-20
      • 2011-08-30
      • 2017-06-11
      • 1970-01-01
      相关资源
      最近更新 更多