【转载】Shader山下(二十三)GrabPass 与 UsePass

361 阅读2分钟

原文链接

版权声明:本文为CSDN博主「凯奥斯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:blog.csdn.net/ecidevilin/…

正文

通道(Pass)是子着色器(SubShader)的组成部分,每个 Pass 代表 对象被渲染一次

例如:

Shader "Custom/pass/Pass" {
	Properties {
	}
	SubShader {   
	    Tags { "RenderType"="Opaque" }
	    LOD 200
            Pass {
                    CGPROGRAM
                    #pragma vertex vert_img
                    #pragma fragment frag
                    #pragma fragmentoption ARB_precision_hint_fastest
                    #include "UnityCG.cginc"

                    fixed4 frag(v2f_img i) : COLOR
                    {
                            return fixed4(1,0,0,1);
                    }
                    ENDCG
            }
            Pass {

                    Blend One One

                    CGPROGRAM
                    #pragma vertex vert_img
                    #pragma fragment frag
                    #pragma fragmentoption ARB_precision_hint_fastest
                    #include "UnityCG.cginc"

                    fixed4 frag(v2f_img i) : COLOR
                    {
                            return fixed4(0,1,0,1);
                    }
                    ENDCG
            }
	}
	FallBack "Diffuse"
}

这段 Shader(的 SubShader)中有两个 Pass,第一个 Pass 的片元着色器返回了 红色,第二个 Pass 的片元着色器返回了 绿色,并且在第二个着色器中使用了 Blend One One 的混合方法(参考 Shader 山下(十八)混合(Blend)命令),这样两个颜色便会加在一起,得到如图所示的效果。

image.png

如果要介绍多个 Pass 的写法,可能够写好多篇博客了,我们先放在一遍,以后再讲。

本文要介绍的是两种特殊的 Pass:GrabPassUsePass

GrabPass

GrabPass 用于 获取当前屏幕 的纹理(Texture)。

例如:

Shader "Custom/pass/Grab" {
	Properties {
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		GrabPass
		{
		}   
		Pass {
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest
			#include "UnityCG.cginc"
 
                        sampler2D _GrabTexture;
 
			fixed4 frag(v2f_img i) : COLOR
			{
				return tex2D(_GrabTexture, i.uv);
			}
			ENDCG
                }
	}
	FallBack "Diffuse"
}

我们可以得到这样的效果:

image.png

GrabPass 获取当前屏幕的纹理默认保存在 _GrabTexture 里。 但是并不会把顶点和片元信息传递给 GPU,所以在 GrabPass 之后,我们需要再添加一个 Pass,对 _GrabTexture 进行操作。

另外,我们可以在 GrabPass 里添加一个字符串来为 修改纹理的变量名

例如:

GrabPass
{
    "_GrabTex"
}  

那么原来的 _GrabTexture 就被取代,都要替换成 _GrabTex

GrabPass 里面无法使用命令或者代码,除了 Name(不知道意义何在)和 Tags(参考 Shader山下(十九)标记Tag)。

UsePass

UsePass 实际上不是 Pass,而是 调用其他 的 Pass 的指令。

例如我们为 Custom/pass/Pass 的第一个 Pass 命名。在 Cg 程序之外添加:

Name "RED"

并且新建一个 Shader:

Shader "Custom/pass/Use" {
	Properties {
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		UsePass "Custom/pass/Pass/RED"
	}
	FallBack "Diffuse"
}

我们就可以看到纯红色的对象了。

image.png

UserPass 后面跟的是 Shader 的名称或 Pass 的名称,Pass 的名称 必须 全大写。(Pass 里命名的时候没有这种要求,不过建议还是相互统一比较好)

我们上面说过,GrabPass 里面可以使用 Name 命令,所以也可以使用 UsePass 调用某个 GrabPass(同样不知道意义何在)。