关于Unity Shader的学习笔记(八)

本文深入探讨Unity Shader编程,包括ShaderLab属性类型、CG变量类型、顶点片元函数编写、Shader内置文件使用及自定义函数封装。解析Unity表面着色器、Pass块应用,以及Shader与材质、Cube交互原理。
记得在笔记四中整理了shaderlab里用到的属性类型,在上一篇笔记中又引入了CG语言的变量类型,当我们在properties块中申明属性时,为了在CG代码中可以访问到对应的属性,就需要在CG代码片段中定义一个新的变量,或者可以理解为重新申明。所以在这里要大致总结一下,具体如下图:
这里有几个点要说明一下,顶点片元可以抽象的理解为笔记四总结的渲染管线里的几何阶段和光栅阶段,是一个shader不可缺少的部分。另外我们知道Unity表面着色器是在顶点片元着色器上的又一层封装,写代码时是不需要pass代码块的,用#pragma surface....来标注此Shader是表面着色器。但当我们自己去写顶点片元函数时则就要求SubShader代码块中有且至少有一个Pass块。在引入Shader内置文件说明之前我们还是先简单的撸段代码,打开Unity工程新建一个Standard Surface Shader,一个材质,一个Cube。之后双击打开新建的Shader,清空里面的代码手写一个顶点片元函数,如下图: 之后将写的shader赋给材质,材质赋给场景中的Cube,不出什么其他问题的话应该是如下图的样子: 我们可以看到在Game视图中什么都没显示,在Scene视图中显示一个绿色的长方形,而Cube你在不选中的情况下也是透明不显示的。在这里要解释说明一下,我们在shader代码中没有引入Properties,也没有FallBack,只是自己定义手写了一个顶点函数和片元函数,产生上图中的现象也算意料之内。一般情况下是将物体比如Cube的纹理,颜色等参数写入到Properties中,之后在SubShader中引入使用,而当没有Properties时,那当然就得不到Cube的顶点纹理信息,通过渲染后的结果就是透明不显示。另外要补充一点CPU是通过MeshRender组件将物体的信息传递到Shader中。另外我们在顶点函数中定义float2的输入参数用POSITION语义修饰默认情况下是上下左右到边界的一半,在笔记六中有总结到裁剪立方体分量范围是[-1,1],因此可以理解为Scene视图中的绿色长方形中心点为[0,0],右上角是[0.5,0.5],左下角是[-0.5,0.5],所以在改变视图大小的时候,绿色长方形边界始终是屏幕中心点到屏幕边界的一半。如下图: 接着,我们把代码稍微改动一下,在片元函数中定义float类型的参数,赋予不同的值,之后再传给输出参数col,不出什么意外情况长方形应该变为红色,这里主要是了解下float、float4的类型作用和意义,如下图: 还有half和fixed类型,half类型是float的一半,同样也有half2、half4,在CG中最多只有四阶,对于float、fixed类型也一样。fixed类型是一个有符号位的9位整数,我们可以这样来剖析一下,去掉符号位,一个fixed型的数可以表示的范围为2^8(^表示次方)=256,3个fixed则就是256^3=16777216。这个数字也就是所谓的24位真彩色。这有点优化的层面在里面,如果没有其他特殊要求的话一般在处理颜色分量的时候可以不用float类型转用fixed就足以满足要求了。就拿上述的例子来说可以将float相应的换成fixed,float4换成fixed4,代码依然正常运行。 在CG中也是支持宏的,如下图: 在CG中可以编写自己的函数方法,如下图: 有时候我们肯定有这样的需求,编写了很多的Shader,但是想要在不同的Shader中使用自己编写的函数方法,这时就引入了内置文件。Unity本身是为我们提供了一些非常有用的变量和帮助函数,在使用时一般在代码中使用#include把这些指令包含进来。可以在Unity安装目录下的Data\CGIncludes文件夹中找到这些内置文件,以.cginc结尾的都是。可以使用VS打开这些文件看一下里面的函数和变量。 当然,这时候我们就可以将自己编写的函数方法放到一个.cginc文件里,以后在使用的时候直接#include 文件名就可以了,例如我们将上面的cusFun函数保存一个.cginc文件,操作是先打开Unity安装目录下的Data\CGIncludes文件夹,之后为了和官方原有的文件区别开,新建一个文件夹,名字自定义,我这里取名Custom,如下图: 之后打开Custom文件夹,在里面新建一个.txt文本文件,重命名为MyCustom.cginc,你可以取自己的名称,只要文件类型是.cginc就行,如下图: 之后回到VS中,执行Ctrl+O打开文件,找到刚才的MyCustom.cginc文件打开,将之前写的cusFun函数方法剪切到里面,如下图: 之后保存,这里保存要注意编码保存为UTF8格式,如下图: 保存之后,回到上面的代码把关于cusFUN的申明删掉,加入#include "Custom/MyCustom.cginc",如下图,保存运行正常。 在编写Shader的时候应该会看到诸如POSITION、SV_POSITION、COLOR0这些大写的语义,通俗的理解这些语义可以让Shader知道从哪里读取数据,并把数据输出到哪里。语义本身是CG/HLSL提供的,Unity只是支持了部分并没有支持全部。Unity为了方便对模型数据的传输,对一些语义进行了特别含义的规定,例如在顶点输入结构体a2f用TEXCOORD0来描述texcoord,Unity会识别TEXCOORD0语义,以把模型的第一组纹理坐标填充到texcoord中,有时候即便语义的名称一样,但出现的位置不一样,含义也不同,后面遇到详细会说明。在Direct10以后,有了一种新的语义类型,是以SV开头,称为系统数值语义,例如前面的SV_POSITION,表示经此语义修饰的参数包含了光栅化的变换后的顶点坐标,使用这些语义的变量是不能够随便赋值的。下面是一些常用的语义,大致整理了下,后续遇到也会标注说明:
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值