Shader着色器语法:编程
在Unity引擎中,为了方便用户和咱们的引擎沟通,Unity创造了一种简单语法,方便咱们与引擎的交流,这个语法Unity官方称为ShaderLab语法;缓存
1、ShaderLab语法格式:函数
Shader “着色器名称”测试
{优化
// 花括号期间的东西就是着色器的源代码spa
}对象
一、Shader中的方法:SubShader;队列
SubShader时Shader当中的方法成员,它在一个Shader脚本中是能够存在多个的,可是多个SubShader并不表明这些SubShader都会执行,Unity引擎会自动寻找能够在当前状况下运行的SubShader对象;图片
注意,每一个Shader都必需要有一个SubShader对象;it
Shader “着色器名称”
{
// 花括号期间的东西就是着色器的源代码
SubShader // 第一个
{
// 下面的代码就是着色器实际绘制代码
}
SubShader // 第二个
{
}
. . .
SubShader // 第N个
{
}
}
二、SubShader中的执行过程: Pass;
Pass语法块,其实是用来作最总渲染的代码位置,咱们的固定着色器和Cg语言可编程着色器都必须写在Pass块当中。
注意:Pass在SubShader不必定存在,当咱们在使用Unity给咱们提供的Surface(表面着色器)语法的时候就能够不写Pass过程,Pass过程决定了你的绘制次数,若是只有一个Pass过程,那么你的DrawCall就是1,若是产生多个Pass过程就必定会产生多个DrawCall,DrawCall越大你的绘制效率就越低!
Shader “着色器名称”
{
// 花括号期间的东西就是着色器的源代码
SubShader // 第一个
{
// 下面的代码就是着色器实际绘制代码
Pass
{
// 固定着色器代码或者是可编程着色器代码
}
}
}
2、固定着色器语法:
由于固定着色器只能改变最终输出色,因此,咱们这里只能控制色彩的变换,下面就是控制色彩的语法:
Color:
// 语法
Color (R, G, B, A)/[变量名(必定是颜色变量)]
设定对象的纯色是否有效,他对灯光无任何影响,他属于自发光;
Lighting:
Lighting on/off
表示当前渲染物体是否接受灯光的变化影响,在这里若是你只有自发光,灯光的开关是无用的,若是你开了灯那么自发光(Color)就会失效效果!
Material Block 材质块:
主要包含材质如何和灯光产生做用,如下属性就是对于灯光色彩的反应属性:
一、Diffuse (R, G, B, A)/[变量名(必定是颜色变量)]
表示材质块中漫反射的颜色,也是物体的基础色彩;
二、Specular (R, G, B, A)/[变量名(必定是颜色变量)]
表示在漫反射的基础上叠加上高光色彩;
三、Shininess Number/[变量(必定是一个float类型的)]
表示对高光的光泽度的改变,范围在0.0 - 1.0之间,0的时候会出现更大的高光反射,1的时候会得到一个细微的亮斑;
四、Amibent (R, G, B, A)/[变量名(必定是颜色变量)]
表示环境光色彩的影响;
五、Emission (R, G, B, A)/[变量名(必定是颜色变量)]
自发光色彩,当不被任何光照照射的时候的一种颜色;
材质块中颜色的影响关系:
Emission颜色是最高等级的颜色,他能够覆盖掉漫反射颜色,若是没有Emission的存在,漫反射才是主要颜色:
最终色彩的生成公式:
Amibent Color * Render Setting菜单下的环境光颜色 + (Light Color * Diffuse Color + Light Color * Specular Color) + Emission;
Cull:
裁减渲染,将不须要的部分剔除掉,有如下几种方式:
一、front:表示将顺时针渲染的面裁减掉,不绘制了;
二、back:表示将逆时针渲染的面裁剪掉;
三、off:表示不执行任何裁剪,这样正面背面都会绘制,加剧了GPU负担;
3、深度测试:
一、什么是深度:
深度其实就是该像素点在3D世界中距离摄像机的距离,深度值(Z轴)越大,则离摄像机越远;
二、什么是深度缓冲:
深度缓冲中记录了每一个像素点的深度值,若是启用了深度缓冲区,在绘制每一个像素以前,3D API函数会把它的深度值和已存储的像素点的深度值进行比较,若是新像素的深度值 < 原先像素的深度值,则新像素就替代原来的像素;反之,新像素值会被遮挡,新像素的颜色和深度值就会被丢弃,最终屏幕上显示的就是深度缓存中深度对应的像素点的颜色!
三、什么叫深度测试:
新像素的深度值(Z轴值)和旧像素的深度值进行比较的过程;
四、为何须要深度测试:
能够表达物体之间遮挡关系,因此咱们须要深度测试;
在ShaderLab中咱们使用的深度测试和深度缓存写:ZTest, ZWrite;
Unity引擎由于是3D引擎因此ZTest, ZWrite都是默认打开的,若是你不写表示他们都开启,咱们能够在他们以后加入off关键字表示关闭某一个选项;
4、属性:
咱们设置属性实际上是为了让咱们的“检视体面板”中可以设定颜色,贴图或者一些常规属性的东西,这样咱们就能够手动的调节他;
属性块关键字:Properties { // 属性内容 }
注意:属性块只能写在全部SubShader之上,不能随便乱写,并且他必须在全部的SubShader以外。咱们也能够不去写Properties;
属性的定义方式:
变量名( “在检视体面板中显示的名字”, 属性的数据类型) = 属性的默认值
注意:属性的默认值必须写,不得省略;
一、Color:表示当前属性是用来设定颜色的;
二、Range(min, max):表示当前属性是用来设定一个区间的数字,范围在min 至 max之间;
三、2D:表示当前属性使用的是2D纹理贴图,能够是任意类型的图片,(tga, png, psd, jpg, jpeg, bmp, 包括法线贴图);他的默认值: “white” {}
四、Float: 表示当前属性是一个浮点数字;
五、Vector: 表示当前属性是一个4维的向量;
六、Cube:表示立方体贴图,主要在天空盒中使用;
5、纹理设定:
格式:SetTexture[纹理的变量对象]{[命令选项]}
命令选项:
combine: 将两个颜色源混合,混合的源能够是previous(上一次的结果);
constant(常量颜色值)、primary(顶点的颜色值)、texture(纹理颜色值)中的一种;
constantColor:用来设定一个常量颜色值与纹理色混合;
matrix: 对当前纹理进行矩阵扭曲;
例如:
一、直接使用纹理颜色: SetTexture[_MainTexture] { combine texture }
二、让纹理的颜色和常量色彩混合 SetTexture[_MainTexture]{ constantColor[_Color] combine constant * texture }
三、咱们但愿顶点色彩和纹理颜色混合 SetTexture[_MainTexture]{ combine primary * texture }
四、咱们但愿顶点和常量颜色混合到纹理色中 SetTexture[_MainTexture]{ constantColor[_Color] combine constant * texture * primary }
6、标签属性;
标签的用户在于定义当前的着色器代码是能够支持你定义的类型方式,若是超出了这个范围,那么当前的着色器代码会失效;
标签格式:Tags{//标签类型和值}
一、SubShader内部标签:
他的标签主要用来描述当前子着色器的渲染顺序;
顺序标签:”Queue”;
Unity引擎预设值:
一、”BackGround”. 值为1000,好比天空盒;
二、”Geometry”. 几何体。值为2000,大部分物体都在这个队列中,不透明物体都在这里,这个队列内部的物体的渲染顺序会有进一步的优化(按照深度值进行从近到远的绘制);
三、“AlphaTest”。若是须要进行Alpha测试的物体就绘制在这一层,值为2450;
四、“Transparent”. 有透明绘制需求的物体在这一层绘制,值为3000;
五、”Overlay”. 在镜头上做效果处理的操做在这一层,好比镜头光晕效果,值为4000;
用户也能够自定义任意值,可是必定要基于系统默认值来增长或者减小,不能直接给一个数值。例如:Tags{ “Queue”=“Geometry+10” }
渲染类型标签:”RenderType”:
一、”Opaque”:表示实体对象,没有透明通道的概念,若是你非要给他透明通道,他就忽略你的透明通道;
二、“Tranparent”:表示能够绘制带有Alpha通道的物体;
三、“BackGround”:表示天空盒绘制方式;
四、“Overlay”:表示镜头上的绘制效果,例如辉光;
例如:咱们但愿当前绘制支持Alpha透明那么咱们能够这样设置: Tags{“RenderType”=“Transparent” “Queue”=“Transparent”}
其余的设置:
若是咱们想忽略透视矩阵:”IgnoreProjector”=“true” 这样咱们就支持摄像机的正交矩阵了
若是咱们须要当前渲染须要支持精灵的切割图:"CanUserSpriteAtlas"="True"
二、Pass内部标签:
Pass中的Tags主要用来控制对灯光的执行方式,Tags决定了你的Pass过程是在什么级别的灯光渲染下执行的,高级别能够兼容低级别,反过来不行;
在标签内部能够制定当前过程所能支撑的渲染级别:
例如:
// 对顶点光照的灯光模式
Tags{ “LightMode”=“Vertex” }
// 对于前置光照
Tags{ “LightMode”=“ForwardBase” }
// 对于前置光照追加光源
Tags{ “LightMode”=“ForwardAdd” }
// 对于迟延光照
Tags{“LightMode”=“PrepassBase”}
// 实时渲染
Tags{ “LightMode”=“PrepassFinal” }
7、Alpha通道测试
Alpha通道的测试,发生在图像最终进入屏幕以前的最后一刻;
启用通道测试的关键字:AlphaTest;
格式:AlphaTest off // 表示关闭Aplha通道测试;
格式:AlphaTest comparsion Alphavalue // 表示让引擎绘制的时候忽略掉必定范围的值;
comparsion:表示比较运算符;
大于(Greater): 仅渲染alpha 值大于 Alphavalue 的像素
大于等于(GEqual): 仅渲染alpha 值大于等于 Alphavalue 的像素
小于(Less): 仅渲染alpha 值小于 Alphavalue 的像素
小于(LEqual): 仅渲染alpha 值小于等于 Alphavalue 的像素
等于(Equal): 仅渲染alpha 等于 Alphavalue 的像素
不等于(NotEqual): 仅渲染alpha 不等于 Alphavalue 的像素
说明用途,AlphaTest是用来忽略掉指定范围的像素对象,可是他不能对颜色的还原有直接的帮助,若是想让颜色按照本身的需求正常的还原回来,咱们须要借助颜色混合命令;
Aplha颜色混合命令为: Blend
当图像被渲染的时候,全部着色器执行之后,全部贴图都被按照颜色本身的需求显示在屏幕上,Blend能够经过计算值来限定颜色的表达;
Blend off
关闭混合功能;
Blend SrcFactor DestFactor
启动配置混合功能。产生的颜色被乘以 SrcFactor,已经存在屏幕上的颜色乘以DestFactor,而且将二者叠加在一块儿;
SrcFactor和DestFactor能够取如下值:
One
表示值为1,使用此设置来让源或目标颜色彻底经过;
Zero
表示值为0,使用此值用来删除源或者目标色;
SrcColor
表示使用源颜色值来作混合运算;
DstColor
表示使用目标色的值来作混合运算;
SrcAplha
表示使用源像素的Alpha通道值来与颜色混合运算;
DstAlpha
表示使用目标像素的Alpha通道值来与颜色混合计算;
OneMinusSrcColor
表示一个公式 (1 - source color)
OneMinusSrcAlpha
表示一个公式(1 - source aplha)
OneMinusDstColor
表示一个公式 (1 - dest color)
OneMinusDstAlpha
表示一个公式(1 - dest aplha)
混合的经常使用组合:
SrcAlpha OneMinusSrcAlpha 表示标准混合,该绘制绘制,不应绘制的丢弃
One One 表示添加剂,让颜色的饱和度达到最大;
One OneMinusDstColor 软性添加剂,根据背景颜色深度,若是背景深度越大那么前景颜色就越鲜明;
DstColor Zero 与后面背景进行融合;
DstColor SrcColor 让后面背景颜色的融合度更深;