Unity3D教程宝典之Shader篇:第二十三讲GrabPass

转载自风宇冲Unity3D教程学院


GrabPass是一种特殊的pass类型。当物体将要被绘制时,它抓取屏幕内容并绘制到一张texture里。
总体来说GrabPass开销较大,不如 AlphaBlend等指令。故能用AlphaBlend等指令实现的效果尽量用指令,不得不用GrabPass时才用GrabPass。

(1)GrabPass{} 抓取当前屏幕内容,每次使用的开销都非常昂贵。 texture用_GrabTexture获取(2)GrabPass{"TextureName"}将抓取屏幕内容并保存至一张texture里。每帧只为第一次使用这张纹理的物体做一次,这种更高效

例1:ShaderLab用法
场景背景如下


在前端放一个cube,shader如下

Shader "Custom/MyGrabPass" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
     SubShader {
        // Draw ourselves after all opaque geometry
        Tags { "Queue" = "Transparent" }
        // Grab the screen behind the object into _GrabTexture
        GrabPass { }
        // Render the object with the texture generated above, and invert it's colors
        Pass {
            SetTexture [_GrabTexture] { combine one-texture }
        }
    }
}

  

效果如下



例2:
有背景如下


在前端新建一个旋转为(90,180,0)的plane,代码如下

Shader "Custom/MyGrabPass" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags{"Queue"="Transparent"}
     
        GrabPass
        {
        }
       
        pass
        {
            Name "pass2"
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
           
            #include "UnityCG.cginc"
            sampler2D _GrabTexture;
            float4 _GrabTexture_ST;
            struct v2f {
                float4  pos : SV_POSITION;
                float2  uv : TEXCOORD0;
            } ;
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv =  TRANSFORM_TEX(v.texcoord,_GrabTexture);
                return o;
            }
            float4 frag (v2f i) : COLOR
            {
                float4 texCol = tex2D(_GrabTexture,i.uv);
                return texCol;
            }
            ENDCG
        }
    }
}

  

效果如下,就是抓取了屏幕背景并贴到前端的plane上


但是uv上下反了,于是
把代码36行的float4 texCol = tex2D(_GrabTexture,i.uv);
改为 float4 texCol = tex2D(_GrabTexture,float2(i.uv.x,1-i.uv.y));
效果如下


Grabpass并指定texture名称,效果也一样

Shader "Custom/MyGrabPass" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags{"Queue"="Transparent"}
     
        GrabPass
        {
            "_MyGrabTexture"
        }
       
        pass
        {
            Name "pass2"
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
           
            #include "UnityCG.cginc"
            sampler2D _MyGrabTexture;
            float4 _MyGrabTexture_ST;
            struct v2f {
                float4  pos : SV_POSITION;
                float2  uv : TEXCOORD0;
            } ;
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv =  TRANSFORM_TEX(v.texcoord,_MyGrabTexture);
                return o;
            }
            float4 frag (v2f i) : COLOR
            {
                float4 texCol = tex2D(_MyGrabTexture,float2(i.uv.x,1-i.uv.y));
                return texCol;
            }
            ENDCG
        }
    }
}

  

posted @ 2015-03-11 12:13  zhangdongli  Views(940)  Comments(0Edit  收藏  举报