https://docs.unity3d.com/Manual/SL-Reference.html
简单示例
Unity3D支持三种Shader(固定功能管线着色器、表面着色器、顶点片段着色器)都需要通过ShaderLab代码来组织:
下面以一个简单的例子介绍ShaderLab的语法:
Shader "Custom/Simple Colored Lighting" { // 名称
Properties {
// 定义一个名为Main Color的颜色属性
_Color("Main Color", Color) = (1,0.5,0.5,1)
}
// Shader的实现代码
SubShader {
Pass {
Material {
Diffuse [_Color]
}
Lighting On
}
}
}
关键字解释:
Shader根命令:每个着色器都需要定义一个唯一的Shader根命令。结构如下:
Shader "着色器名称"{ Properties{} // 属性定义 SubShader{} // 子着色器1 SubShader{} // 子着色器2 ... Fullback "备用着色器名称" // 如果所有的子着色器都不能运行,则使用备用着色器 }
- Properties属性定义:用来定义着色器中使用的贴图资源或者数值参数等。这些属性会在Inspector视图的材质界面中显示,可以方便地进行设置和修改。在示例中,Properties代码块里定义了一个名为Main Color的颜色属性。
- SubShader子着色器:一个着色器包含一个或者多个子着色器。当Unity使用着色器渲染时,会丛上到下遍历子着色器,找到第一个能被用户设备支持的子着色器,并使用该着色器渲染,如果没有找到着色器能够运行,Unity则会使用备用着色器。
- Fullback备用着色器:备用着色器一般会指定一个对硬件要求最低的Shader,当所有子着色器不运行时,Unity会使用该着色器来运行。
Properties属性
着色器的属性定义在属性代码块中,语法为:
Properties{
属性列表
}
着色器中可以定义的属性表如下:
语法 | 说明 |
---|---|
名称(“显示名称”, Vector)=默认值向量 | 定义一个四维向量属性 |
名称(“显示名称”,Color)=默认颜色值 | 定义一个颜色(取值为0~1的四维向量)属性 |
名称(“显示名称”, Float)=默认浮点数值 | 定义一个浮点数属性 |
名称(“显示名称”, Range(min,max))=默认浮点数值 | 定义一个浮点数范围属性,取值从min到max |
名称(“显示名称”, 2D)=默认贴图名称{选项} | 定义一个2D纹理属性 |
名称(“显示名称”, Rect)=默认贴图名称{选项} | 定义一个矩形纹理属性(非2的n次幂) |
名称(“显示名称”, Cube)=默认贴图名称{选项} | 定义一个立方体纹理属性 |
表中的“名称”指的是Shader代码中使用的属性名称,“显示名称”指的是Inspector视图中用于显示的名称字符串。“选项”指的是一些纹理的可选参数,包括如下几项:
- TexGen:纹理生成模式,可以是ObjectLinear、EyeLinear、SphereMap、CubeReflect、CubeNormal中的一种,这些模式与OpenGL的纹理生成模式相对应。如果使用了自定义的定点程序,那么该参数会被忽略。
- LightmapMode:如果使用该选项,那么纹理将受渲染器的光照贴图参数影响。纹理将不会从材质中获取,而是取自渲染器的设置。
Properties {
// 定义一个名为Main Color的颜色属性
_Color("Main Color", Color) = (1,0.5,0.5,1)
_Vector("Main Vector", Vector) = (1,1,1,1)
_Float("Main Float", Float) = 0.1
_Range("Main Range", Range(1,5)) = 5
_2D("Main 2D", 2D) = "" {}
_Rect("Main Rect", Rect ) = "" {}
_Cube("Main Cube", Cube) = "" {}
}
SubShader子着色器
Unity的着色器包含一个或者多个子着色器。在渲染时会从上到下遍历着色器列表,找到第一个能运行的着色器用于渲染。
子着色器由“标签(可选)”、“通用状态(可选)”、“Pass列表”组成。
语法结构为:
SubShader {
[Tags标签]
[CommonState通用状态]
Pass def [Pass def ... Pass定义]
}
在Unity使用子着色器进行渲染时,每个Pass都会渲染一次对象(有时根据光照交互情况会渲染多次)。由于每次渲染都会造成一定的开销,因此在硬件能力允许的情况下,尽量减少不必要的Pass数量。
下面是子着色器的一个简单例子(使用固定管线功能着色器),代码如下:
SubShader {
Pass {
Lighting Off // 关闭灯光
SetTexture [_2D] {} // 使用纹理MainTex
}
}
在每个Pass中,对象的几何体都被渲染一次。定义Pass的语法如下:
Pass {
[Name and Tags 名称和标签]
[Render Setup 渲染设置]
[Texture Setup 纹理设置]
}
Pass包含一个可选的名称和标签列表、一个可选的渲染命令列表和一个可选的纹理列表。
名称和标签(Name and tags)
可以定义Pass的名称以及任意数量的标签。为Pass命名后,可以在别的着色器中通过Pass名称来引用他。标签则可以用来向渲染管线说明Pass的意图,他是“键值对”的形式。
标签类型 | 说明 | 例子 |
---|---|---|
Queue | 控制渲染顺序,指定该物体属于哪一个渲染队列,通过这种方式可以保证所有的透明物体可以在所有不透明物体后面被渲染,也可以自定义使用的渲染队列来控制物体的渲染顺序 | Tags { "Queue"="Transparent" } |
RenderType | 对着色器进行分类,例如这是一个不透明的着色器,或是一个透明的着色器等。这可以被用于着色器替换(Shader Replacement)功能 | Tags { "RenderType"="Opaque" } |
DisableBatching | 一些SubShader在使用Unity的批处理功能时会出现问题。 | Tags {"DisableBatching"="True"} |
ForceNoShadowCasting | 控制使用该SubShader的物体是否会使用投影 | Tags {"ForceNoShadowCasting"="True" } |
IgnoreProjector | 如果该标签值为”True”,那么使用该SubShader的物体将不会受Projector的影响。通常用于半透明物体 | Tags {"IgnoreProjetor"="True"} |
CanUseSpriteAtlas | 当该SubShader是用于精灵(Sprite)时,将标签设置为”False” | Tags { "CanUseSpriteAtlas"="False" } |
PreviewType | 指明材质面板将如何预览该材质。默认情况下,材质将显示为一个球形,也可以设置为”Plane” “Skybox” | Tags { “PreviewType”=”Plane” } |
Pass的标签类型
Pass中的标签类型 | 说明 | 例子 |
---|---|---|
LightMode | 定义该Pass在Unity的渲染流水线中的角色 | Tags {"LightMode"="ForwardBase"} |
RequireOptions | 用于指定当满足某些条件时才渲染该Pass,它的值是由空格分隔的字符串。目前支持的选项有:SoftVegetation. | Tags {"RequireOptions"="SoftVegetation"} |
渲染设置(Render Setup)
Pass里可以设置图形硬件的各种状态,例如开启Alpha混合、开启雾效等。
Pass中可用的渲染设置命令
命令 | 说明 |
---|---|
Material {} | 材质。定义一个使用顶点光照管线的材质。 |
Lighting | 光照。设置光照,取值为On或Off |
Cull | 裁剪。设置裁剪模式,模式包括Back、Front、Off |
ZTest | 深度测试。设置深度测试模式,模式包括Less、Greater、LEqual、GEqual、Equal、NotEqual、Always |
ZWrite | 深度缓存写入。设置深度缓存写入开关,取值为On和Off |
Fog{} | 雾效。设置雾效参数 |
AlphaTest | Alpha测试,设置Alpha测试,模式有Less、Greater、LEqual、REqual、Equal、NotEqual、Always |
Blend | Alpha混合,设置Alpha混合模式 |
Stencil | 蒙版(新增)。用蒙版来实现像素的取舍操作,选项有Keep、Zero、Replace、IncrSat、DecrSat、Invert、IncrWrap、DecrWrap |
Color | 颜色。设置顶点光照关闭时使用的颜色值。 |
ColorMask | 颜色遮罩。设置颜色遮罩,当值为0时关闭所有的颜色通道的渲染,取值为RGB/A/O或R/G/B/A的任意组合 |
Offset | 深度偏移。设置深度偏移 |
SeparateSpecular | 高光颜色。开启或关闭顶点光照的独立高光颜色,取值为On或Off |
ColorMaterial | 颜色集。当计算顶点光照时 |
纹理设置(Texture Setup)
在设置渲染状态以后,可以指定一些要使用的纹理及其混合模式。纹理设置的语法为:
SetTexture 纹理属性 {[命令选项]}
纹理设置用于固定功能管线,如果使用表面着色器或者自定义顶点及片段着色器,那么此设置会被忽略。
SetTexture的命令选项包括3种:
- combine:将两种颜色混合,混合的源可以是previous(上一次SetTexture的结果)、constant(常量颜色值)、primary(顶点颜色)、texture(纹理颜色)的一种。
- constantColor:设置一个常量颜色值。
- matrix:设置矩阵对纹理坐标进行变换
另外,Unity中还可以使用两种特殊的Pass来重用一些常用的功能,或者实现一些高级特效。
UsePass:可以通过UsePass来重用其他着色器中命令的Pass。例如:
UsePass "Specular/BASE" // 使用高光着色器Specular中命名为Base的passGrabPass:将屏幕抓取到一个纹理中,供后续的Pass使用,可以通过GrabTexture来访问。
Fallback备用着色器
Fallback语句一般位于所有子着色器之后。
Fallback语句的用法有两种:
- Fallback”备用着色器名称”,例如Fallback “Diffuse”
- Fallback Off,显示声明不适用备用着色器,当没有子着色器能够运行的时候也不会有警告。