Shader着色器基本语法

原创
2016/08/07 17:36
阅读数 592

Shader着色器语法:

在Unity引擎中,为了方便用户和我们的引擎沟通,Unity创造了一种简单语法,方便我们与引擎的交流,这个语法Unity官方称为ShaderLab语法;

 

一、ShaderLab语法格式:

 

Shader “着色器名称”

{

// 花括号期间的东西就是着色器的源代码

}

 

1、Shader中的方法:SubShader;

SubShader时Shader当中的方法成员,它在一个Shader脚本中是可以存在多个的,但是多个SubShader并不代表这些SubShader都会执行,Unity引擎会自动寻找可以在当前情况下运行的SubShader对象;

 

注意,每个Shader都必须要有一个SubShader对象;

 

Shader “着色器名称”

{

         // 花括号期间的东西就是着色器的源代码

         SubShader // 第一个

         {

                   // 下面的代码就是着色器实际绘制代码

         }

        

         SubShader // 第二个

         {

         }

 

         . . .

 

         SubShader // 第N个

         {

         }

}

 

2、SubShader中的执行过程: Pass;

Pass语法块,实际上是用来做最总渲染的代码位置,我们的固定着色器和Cg语言可编程着色器都必须写在Pass块当中。

 

注意:Pass在SubShader不一定存在,当我们在使用Unity给我们提供的Surface(表面着色器)语法的时候就可以不写Pass过程,Pass过程决定了你的绘制次数,如果只有一个Pass过程,那么你的DrawCall就是1,如果产生多个Pass过程就一定会产生多个DrawCall,DrawCall越大你的绘制效率就越低!

 

Shader “着色器名称”

{

         // 花括号期间的东西就是着色器的源代码

         SubShader // 第一个

         {

                   // 下面的代码就是着色器实际绘制代码

                   Pass

                   {

                            // 固定着色器代码或者是可编程着色器代码

                   }

         }

}

 

 

 

 

二、固定着色器语法:

 

因为固定着色器只能改变最终输出色,所以,我们这里只能控制色彩的变换,下面就是控制色彩的语法:

 

Color:

// 语法

Color (R, G, B, A)/[变量名(一定是颜色变量)]

设定对象的纯色是否有效,他对灯光无任何影响,他属于自发光;

 

Lighting:

Lighting on/off

表示当前渲染物体是否接受灯光的变化影响,在这里如果你只有自发光,灯光的开关是无用的,如果你开了灯那么自发光(Color)就会失效效果!

 

Material Block 材质块:

主要包含材质如何和灯光产生作用,以下属性就是对于灯光色彩的反应属性:

1、Diffuse (R, G, B, A)/[变量名(一定是颜色变量)]

         表示材质块中漫反射的颜色,也是物体的基础色彩;

2、Specular (R, G, B, A)/[变量名(一定是颜色变量)]

         表示在漫反射的基础上叠加上高光色彩;

3、Shininess Number/[变量(一定是一个float类型的)]

         表示对高光的光泽度的改变,范围在0.0 - 1.0之间,0的时候会出现更大的高光反射,1的时候会获得一个细微的亮斑;

4、Amibent (R, G, B, A)/[变量名(一定是颜色变量)]

         表示环境光色彩的影响;

5、Emission (R, G, B, A)/[变量名(一定是颜色变量)]

         自发光色彩,当不被任何光照照射的时候的一种颜色;

 

材质块中颜色的影响关系:

 

Emission颜色是最高等级的颜色,他可以覆盖掉漫反射颜色,如果没有Emission的存在,漫反射才是主要颜色:

 

最终色彩的生成公式:

 

Amibent Color * Render Setting菜单下的环境光颜色 + (Light Color * Diffuse Color + Light Color * Specular Color) + Emission;

 

 

Cull:

裁减渲染,将不需要的部分剔除掉,有以下几种方式:

 

1、front:表示将顺时针渲染的面裁减掉,不绘制了;

2、back:表示将逆时针渲染的面裁剪掉;

3、off:表示不执行任何裁剪,这样正面背面都会绘制,加重了GPU负担;

 

 

三、深度测试:

 

1、什么是深度:

深度其实就是该像素点在3D世界中距离摄像机的距离,深度值(Z轴)越大,则离摄像机越远;

 

2、什么是深度缓冲:

深度缓冲中记录了每个像素点的深度值,如果启用了深度缓冲区,在绘制每个像素之前,3D API函数会把它的深度值和已存储的像素点的深度值进行比较,如果新像素的深度值 < 原先像素的深度值,则新像素就替代原来的像素;反之,新像素值会被遮挡,新像素的颜色和深度值就会被丢弃,最终屏幕上显示的就是深度缓存中深度对应的像素点的颜色!

 

3、什么叫深度测试:

新像素的深度值(Z轴值)和旧像素的深度值进行比较的过程;

 

4、为什么需要深度测试:

可以表达物体之间遮挡关系,所以我们需要深度测试;

 

在ShaderLab中我们使用的深度测试和深度缓存写:ZTest, ZWrite;

 

Unity引擎因为是3D引擎所以ZTest, ZWrite都是默认打开的,如果你不写表示他们都开启,我们可以在他们之后加入off关键字表示关闭某一个选项;

 

 

 

四、属性:

 

我们设置属性其实是为了让我们的“检视体面板”中能够设定颜色,贴图或者一些常规属性的东西,这样我们就可以手动的调节他;

 

属性块关键字:Properties { // 属性内容 }

注意:属性块只能写在所有SubShader之上,不能随便乱写,而且他必须在所有的SubShader之外。我们也可以不去写Properties;

 

属性的定义方式:

 

变量名( “在检视体面板中显示的名字”,  属性的数据类型) = 属性的默认值

 

注意:属性的默认值必须写,不得省略;

 

1、Color:表示当前属性是用来设定颜色的;

2、Range(min, max):表示当前属性是用来设定一个区间的数字,范围在min 至 max之间;

3、2D:表示当前属性使用的是2D纹理贴图,可以是任意类型的图片,(tga, png, psd, jpg, jpeg, bmp, 包括法线贴图);他的默认值: “white” {}

4、Float: 表示当前属性是一个浮点数字;

5、Vector: 表示当前属性是一个4维的向量;

6、Cube:表示立方体贴图,主要在天空盒中使用;

 

 

五、纹理设定:

格式:SetTexture[纹理的变量对象]{[命令选项]}

 

命令选项:

combine: 将两个颜色源混合,混合的源可以是previous(上一次的结果);

constant(常量颜色值)、primary(顶点的颜色值)、texture(纹理颜色值)中的一种;

 

constantColor:用来设定一个常量颜色值与纹理色混合;

matrix: 对当前纹理进行矩阵扭曲;

 

例如:

1、直接使用纹理颜色: SetTexture[_MainTexture] { combine texture }

2、让纹理的颜色和常量色彩混合 SetTexture[_MainTexture]{ constantColor[_Color] combine constant * texture }

3、我们希望顶点色彩和纹理颜色混合 SetTexture[_MainTexture]{ combine primary * texture }

4、我们希望顶点和常量颜色混合到纹理色中 SetTexture[_MainTexture]{ constantColor[_Color] combine constant * texture * primary }

 

六、标签属性;

 

标签的用户在于定义当前的着色器代码是可以支持你定义的类型方式,如果超出了这个范围,那么当前的着色器代码会失效;

 

标签格式:Tags{//标签类型和值}

 

1、SubShader内部标签:

他的标签主要用来描述当前子着色器的渲染顺序;

顺序标签:”Queue”;

Unity引擎预设值:

1、”BackGround”. 值为1000,比如天空盒;

2、”Geometry”. 几何体。值为2000,大部分物体都在这个队列中,不透明物体都在这里,这个队列内部的物体的渲染顺序会有进一步的优化(按照深度值进行从近到远的绘制);

3、“AlphaTest”。如果需要进行Alpha测试的物体就绘制在这一层,值为2450;

4、“Transparent”. 有透明绘制需求的物体在这一层绘制,值为3000;

5、”Overlay”. 在镜头上作效果处理的操作在这一层,比如镜头光晕效果,值为4000;

 

用户也可以自定义任意值,但是一定要基于系统默认值来增加或者减少,不能直接给一个数值。例如:Tags{ “Queue”=“Geometry+10” }

 

渲染类型标签:”RenderType”:

1、”Opaque”:表示实体对象,没有透明通道的概念,如果你非要给他透明通道,他就忽略你的透明通道;

2、“Tranparent”:表示可以绘制带有Alpha通道的物体;

3、“BackGround”:表示天空盒绘制方式;

4、“Overlay”:表示镜头上的绘制效果,例如辉光;

例如:我们希望当前绘制支持Alpha透明那么我们可以这样设置: Tags{“RenderType”=“Transparent” “Queue”=“Transparent”}

 

其他的设置:

如果我们想忽略透视矩阵:”IgnoreProjector”=“true” 这样我们就支持摄像机的正交矩阵了

如果我们需要当前渲染需要支持精灵的切割图:"CanUserSpriteAtlas"="True"

 

2、Pass内部标签:

 

Pass中的Tags主要用来控制对灯光的执行方式,Tags决定了你的Pass过程是在什么级别的灯光渲染下执行的,高级别可以兼容低级别,反过来不行;

 

在标签内部可以制定当前过程所能支撑的渲染级别:

例如:

// 对顶点光照的灯光模式

Tags{ “LightMode”=“Vertex” }

// 对于前置光照

Tags{ “LightMode”=“ForwardBase” }

// 对于前置光照追加光源

Tags{ “LightMode”=“ForwardAdd” }

// 对于迟延光照

Tags{“LightMode”=“PrepassBase”}

// 实时渲染

Tags{ “LightMode”=“PrepassFinal” }

 

 

 

 

七、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 让后面背景颜色的融合度更深;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部