Unity Shader 基础知识(二)

来源:互联网 发布:mac怎么设置壁纸 编辑:程序博客网 时间:2024/06/06 17:50

一、一些不常用的通用指令:

之前忘了说,上一篇所说的通用指令和这些通用指令,几乎都可以单独使用在一个PASS中,即可以写成这种格式:

Pass{BlendOp Min// 定义混合方法Blend SrcAlpha OneMinusSrcAlpha // 定义Alpha混合模式AlphaTest GEqual [_Float]// 定义Alpha测试条件                        //其他CG代码                 }

1.     AlphaTest指令(通道指令):AlphaTest是用来在吸入到帧上之前,做最后一层过滤,对fragment函数所产生的最终颜色的Alpha值进行一个条件比较,满足条件的,才会写入到帧中,不满足的,直接过滤掉。 AlphaTest的格式为:AlphaTest Greater 0.5 ,其中,Greater就是大于的意思,并且Greater可以替换为GEqual,Equal,NotEqual,Less,Lequal,Always,Never,这些词的意思如果不知道的,百度一下。比较关键字后面跟着的值0.5,可以使任意浮点数,并且可以再运行时决定,即这个地方可以填一个变量,这个变量可以使Properties模块里面所定义的变量。但特别需要注意的是,变量名称需要用一对[]括起来,例如:AlphaTest Greater [_Float]

2.    BlendOp指令:上一篇文中说过,在Blend指令中,

最终颜色 = (Shader计算出的点颜色值(自身颜色) * F1)+(点累积颜色(目标颜色) * F2)

而使用BlendOp Max指令,则是把最后加的操作,替换成求最大值,即公式变成

最终颜色 = MAX((Shader计算出的点颜色值(自身颜色) * F1),(点累积颜色(目标颜色) * F2))

BlendOp的选项总共有四种,分别是 Add,Max,Min,Sub,RevSub,详细解释:

Add:源颜色和目标颜色相加,如果不设置,这个就是默认的选项

Sub:用源颜色减去目标颜色

RevSub:目标颜色减去源颜色

Max:源颜色和目标颜色取值最大的

Min:源颜色和目标颜色取值最小的

通常BlendOp指令和Blend指令一起使用,例如:

BlendOp MinBlend SrcAlpha OneMinusSrcAlpha

3.     ColorMask指令:通道遮罩指令,在通常情况下,你渲染的结果的RGBA这四个通道都会被输出,但有时候,你可能只需要输出某几个通道或者不输出

指令格式:ColorMask R/G/B/A/0 ,指令后面RGBA这四个参数可以任意组合,如果参数填0,则表示不输出任何通道。

例如:ColorMask R,表示只输出R通道,就是红色通道,ColorMask RB,只输出红和蓝色通道

4.     GrabPass抓屏操作:GrabPass可以抓取屏幕的内容作为一张贴图,并且对这张贴图命名,若没有命名,则默认为_GrabTexture,通过这个方法,我们可以做一些比较高级的效果,至于有哪些效果,我知道的也不多,只知道可以拿来做镜面反射,直接给出用法实例

Shader "MyShader/GrabPass_Test"{Properties{_MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {} // 定义贴图变量}SubShader{LOD 100Tags{"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent"}Lighting Off// 关闭光照Fog { Mode Off }// 关闭雾化Offset -1, -1// 关闭Z深度的偏移GrabPass{ "_CustomTex" } // 把屏幕截图命名为_CustomTex的贴图Pass{Blend one zero // 定义Alpha混合模式CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata_t{float4 vertex : POSITION;float2 texcoord : TEXCOORD0;fixed4 color : COLOR;};struct v2f{float4 vertex : SV_POSITION;half2 texcoord : TEXCOORD0;fixed4 color : COLOR;};sampler2D _CustomTex; // 同时,这里也要声明截屏贴图变量名,需要与上面的名称一样sampler2D _MainTex;float4 _MainTex_ST;v2f vert (appdata_t v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);o.color = v.color;return o;} fixed4 frag (v2f i) : COLOR{half2 uv = i.texcoord;uv.x = abs(1-uv.x);fixed4 col = tex2D(_CustomTex, uv); // 使用截屏贴图作为纹理return col;}ENDCG}}}
上面这个是,直接将截屏内容输出,没有做任何处理


、Pass块:

一个SubShader可以有多个Pass,一个Pass就是一个渲染通道,就是一个DrawCall,每一个Pass都包含了一个完整的渲染流程。Pass模块里面可以使用CG代码块,这才是最重要的!另外,也可以给这个Pass命名和使用之前说的通用指令来设置属性。

使用CG代码块的地方,需要用CGPROGRAM和ENDCG来包住,以此来声明这段是CG代码,具体的CG用法,我自己也只懂点皮毛,就介绍了。只介绍一些在Unity中写CG的一些固定格式。

拿上面介绍GrabPass的示例代码来做说,首先要先声明顶点着色器和片段着色器函数名,并把CG头文件给包含进来,所以一般的固定开头是

#pragma vertex vert //顶点着色器函数名定义为vert,这个名称可以随便修改,如可以命名为MyVert#pragma fragment frag//片段着色器函数名定义为frag,名称可修改#include "UnityCG.cginc"//把CG头文件包含进来
因为你把顶点着色器和片段着色器函数名分别定义为vert和frag,所以在后面的代码中,就需要有一个名为vert和frag的函数。
v2f vert (appdata_t v) //定义一个名为vert且带返回值的函数{v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);o.color = v.color;return o;} fixed4 frag (v2f i) : COLOR // 定义一个名为frag的函数{half2 uv = i.texcoord;uv.x = abs(1-uv.x);fixed4 col = tex2D(_CustomTex, uv);return col;}
其中片段着色器的返回值是固定的,需要是一个四维的颜色变量,而参数可以是自己定义一个结构体并决定里面要保护什么信息,结构体里面可以保护的信息也是有限制的,都是一些预定好的变量类型,如POSITION表示顶点位置,TEXCOORD0表示第一张纹理的UV,COLOR表示颜色值,具体还有哪些选项,以后再CG笔记里面再记录。



0 0
原创粉丝点击