Shader文件名
//shader路径,这个用来显示在材质上你属性那个位置上
Shader "Custom/MyShader"
{
}
Properties语义
代码结构:
Properties
{
Name ("display name",PropertyType )=DefaultValue
//more...
}
- Name:属性名,用来在Shader中访问这个属性
- display name:在Unity材质面板上的名字
- PropertyType: 属性类型
常用属性
语法 | 说明 |
---|---|
name (“display name”, Range (min, max)) =number | 定义浮点数属性,在检视器中可通过一个标注最大最小值的滑条来修改。 |
name (“display name”, Color) =(number,number,number,number) | 颜色 |
name (“display name”, 2D) =“name” {options } | 2D纹理 |
name (“display name”, Rect) =“name”{ options } | 长方形(非2次方)纹理 |
name (“display name”, Cube) =“name”{ options } | 立方贴图纹理 |
name (“display name”, Float) =number | 浮点数 |
name (“display name”, Vector) =(number,number,number,number) | 四元素的容器(相当于Vector4) |
SubShader 语义块
一个Shader文件至少要有一个SubShader语义块,Unity会扫描所有SubShader语义块,然后选择第一个能够在目标平台上运行的SubShader,如果不支持,就会使用Fallback指定
代码结构:
SubShader
{
//可选
[Tags]
//可选
[RenderSetup]
Pass
{
}
//Other Pass
}
每个Pass代表定义了一个完整的渲染流程
状态设置
剔除模式
1. Cull Back //背面
2. Cull Front //正面
3. Cull Off //关闭剔除
设置深度测试
1. ZTest Less //深度小于当前缓存则通过
2. ZTest Greater //大于
3. ZTest LEqual //小于等于
4. ZTest GEqual //大于等于
5. ZTest Equal //等于
6. ZTest NotEqual //不等于
7. ZTest Always //不论如何都通过
8. ZTest Off //等同于ZTest Always,关闭深度测试等于完全通过
开启/关闭深度写入
1. ZWrite On | Off
混合模式
1. Blend Off:关闭混合(这是默认值)
2. Blend SrcFactor DstFactor:配置并启用混合。生成的颜色将乘以SrcFactor。屏幕上的已有颜色乘以 DstFactor,然后将这两个值相加。
3. Blend SrcFactor DstFactor, SrcFactorA DstFactorA:同上,但使用不同系数来混合 Alpha 通道。
4. BlendOp Op:不将混合颜色相加,而是对它们执行不同的操作。
5. BlendOp OpColor, OpAlpha:同上,但是对颜色 (RGB) 通道和 Alpha (A) 通道使用不同的混合操作
混合系数
以下所有属性对 Blend 命令中的 SrcFactor 和 DstFactor 都有效。源是指计算所得颜色,目标是指屏幕上已有的颜色。如果 BlendOp 在使用逻辑运算,则将忽略混合系数。
模式 | 说明 |
---|---|
One | 值为 1 - 让源或目标颜色通过。 |
Zero | 值为 0 - 删除源或目标值 |
SrcColor | 此阶段的值乘以源颜色值 |
SrcAlpha | 此阶段的值乘以源 Alpha 值 |
DstColor | 此阶段的值乘以帧缓冲区源颜色值 |
DstAlpha | 此阶段的值乘以帧缓冲区源 Alpha 值 |
OneMinusSrcColor | 此阶段的值乘以(1 - 源颜色) |
OneMinusSrcAlpha | 此阶段的值乘以(1 - 源 Alpha) |
OneMinusDstColor | 此阶段的值乘以(1 - 目标颜色) |
OneMinusDstAlpha | 此阶段的值乘以(1 - 目标 Alpha) |
SubShader 标签
这是键值对方式,用来告诉Unity我希望怎样以及如何渲染这个对象
渲染顺序 - Queue 标签
您可以使用 Queue 标签来确定对象的绘制顺序。着色器决定其对象属于哪个渲染队列,这样任何透明着色器都可以确保它们在所有不透明对象之后绘制,依此类推。
有四个预定义的渲染队列,但预定义的渲染队列之间可以有更多的队列。预定义队列包括:
1.Background - 此渲染队列在任何其他渲染队列之前渲染。通常会对需要处于背景中的对象使用此渲染队列。
2.Geometry(默认值)- 此队列用于大部分对象。不透明几何体使用此队列。
3.AlphaTest - 进行 Alpha 测试的几何体将使用此队列。这是不同于 Geometry 队列的单独队列,因为在绘制完所有实体对象之后再渲染经过 Alpha 测试的对象会更有效。
4.Transparent - 此渲染队列在 Geometry 和 AlphaTest 之后渲染,按照从后到前的顺序。任何经过 Alpha 混合者(即不写入深度缓冲区的着色器)都应该放在这里(玻璃、粒子效果)。
5.Overlay - 此渲染队列旨在获得覆盖效果。最后渲染的任何内容都应该放在此处(例如,镜头光晕)。
Shader "Transparent Queue Example"
{
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{
// 着色器主体的剩余部分...
}
}
}
说明如何在透明队列中渲染对象的示例
对于特殊用例,可以使用中间队列。在内部,每个队列由整数索引表示;Background 是 1000,Geometry 是 2000,AlphaTest 是 2450,Transparent 是 3000,Overlay 是 4000。如果着色器使用如下所示的队列:
Tags { “Queue” = “Geometry+1” }
这将使对象在所有不透明对象之后渲染,但在透明对象之前渲染,因为渲染队列索引值将是 2001(几何体索引值加一)。如果您希望始终在其他对象集之间绘制某些对象,那么这非常有用。例如,在大多数情况下,透明的水应该在不透明对象之后绘制,但又要在透明对象之前绘制。
索引值高达 2500 的队列(“Geometry+500”)视为“不透明”,并且会优化对象的绘制顺序以获得最佳性能。 较高索引的渲染队列被认为是“透明对象”并按距离将对象进行排序,从距离最远的对象开始渲染,最后渲染距离最近的对象。天空盒在所有不透明对象和所有透明对象之间绘制。
RenderType 标签
RenderType 标签将着色器分为几个预定义的组,例如,不透明的着色器,或经过 Alpha 测试的着色器等等。着色器替换将使用该标签,在某些情况下还用于产生摄像机的深度纹理。
DisableBatching 标签
使用绘制调用批处理时,一些着色器(主要是进行对象空间顶点变形的着色器)不起作用,这是因为批处理会将所有几何体转换为世界空间,所以“对象空间”丢失。
可使用 DisableBatching 标签来指示这一情况。有三个可能的值:“True”(始终对此着色器禁用批处理)、“False”(不禁用批处理;这是默认值)和“LODFading”(当 LOD 淡化处于激活状态时禁用批处理;主要用于树)。
ForceNoShadowCasting 标签
如果提供了 ForceNoShadowCasting 标签并且值为“True”,则使用该子着色器渲染的对象绝不会投射阴影。对透明对象使用着色器替换并且不希望从其他子着色器继承阴影通道时,这非常有用。
IgnoreProjector 标签
如果提供了 IgnoreProjector 标签并且值为“True”,则使用此着色器的对象不会受到投影器的影响。这对半透明对象非常有用,因为投影器无法影响它们。
CanUseSpriteAtlas 标签
如果着色器用于精灵,请将 CanUseSpriteAtlas 标签设置为“False”,这样在精灵打包到图集内时,该标签将不起作用,(请参阅精灵打包器 (Sprite Packer))。
PreviewType 标签
PreviewType 指示材质检视面板预览应如何显示材质。默认情况下,材质显示为球体,但也可以将 PreviewType 设置为“Plane”(将显示为 2D)或“Skybox”(将显示为天空盒)。
Pass语义块
一个通道 (Pass) 可以定义一个名称 (Name) 和任意数量的标签 (Tags)。这些名称/值字符串用于将通道的意图传达给渲染引擎。
Pass
{
[Name]
[Tags]
[RenderSetup]
//Other code
}
UsePass:
我们可以定义Pass的名词,然后我们可以通过UsePass 命令来直接使用其他Shader的Pass
UsePass "MyShader/MYPASSNAME"
Unity内部会把所有Pass的名称转换为大写字母,因此在使用时必须使用大写
Fallback
在所有子着色器的后面可定义 Fallback。基本上就是说,“如果没有任何子着色器能够在此硬件上运行,则尝试使用另一个着色器中的子着色器”。
语法 Fallback “name”
回退到具有给定**名称 (name) **的着色器,或者…
Fallback Off
显式说明即使没有子着色器可以在此硬件上运行,也不会进行回退并且不会显示警告。
详细信息: Fallback 语句的效果等同于插入其他着色器中的所有子着色器。