UnityShader

UnityShader学习笔记(一)-Shaderlab的基本结构

Shaderlab的基本结构

Shader "ShaderName" {
    Properties {
    // 属性
    }
    //SubShader有且至少有一个
    SubShader{
    //显卡A使用的着色器
    }
    SubShader{
    //显卡B使用的着色器
    }
    Fallback "VertexLit"
}

Shader的命名

Shader "Custom/MyShader" {}

在Shader关键字后“”内为Shader命名,名称为一个层级结构以“/”来进行分割,在为材质选择UnityShader时可以在下拉列表中找到Custom层级下的MyShader。
材质面板中的位置Shader->Custom->MyShader

 

Properties(属性)语义块

properties语义块中包含了各种属性,这些属性会出现在Unity的材质面板中。
properties的基本结构如下
Properties {
Name ("displayName", PropertyType) = DefaultValue
....
}
在上面的结构中Name在Shader中的属性名字,这个名字可以在Shader中访问到,这中名字一般会以下划线为首字符来命名。displayName表示在材质面板中要显示的名字。PropertyType为属性对应的类型,DefaultValue表示初始默认值
Properties语义块中支持的类型
Int                                             如,_Int("Int",Int) = 1
Float                                         如,_Float("Float",Float) =1.2
Range(min,max)                     如,_Range("Range",Range(0.0,5.0)) = 3.0
Color                                        如,_Color("Color",Color) = (1,1,1,1)
Vector                                      如,_Vector("Vector",Vector) = (3,4,5,1)
2D                                             如,_2D("2D",2D) = ""
Cube                                         如,_Cube("Cube",Cube) = "white" {}
3D                                             如,_3D("3D",3D) = "black"{}
其中Int,Float,Range表示数值类型,Range为范围值。Color表示rgba颜色值,为四个0~1之间的浮点数。Vector表示一组四维向量值。2D,Cube,3D表示Tureture纹理属性,默认值为字符串表示贴图名字。

Shader "Custom/ShaderProperties"
{
    Properties{
        _Int("Int",Int) = 1
        _Float("Float",Float) =1.2
        _Range("Range",Range(0.0,5.0)) = 3.0
        _Vector("Vector",Vector) = (3,4,5,1)
        _Color("MainColor",color) = (1,0,0,1)
        _MainTex("MainTex",2d) = "white"{}
    }
}​

Shader中的关键字没有大小写之分

 

SubShader语义块

在ShaderLab中可以存在多个SubShader语义块,但至少包含一个。当Unity需要加载这个UnityShader时,Unity会扫描所有的SubShader语义块,然后选择第一个能够在目标平台上运行的SubShader。如果都不支持的话,Unity就会使用Fallback语义指定的UnityShader。
SubShader语义块的定义通常如下

SubShader{
    // 可选
    [Tags]
    // 可选
    [RenderSteup]
    pass{
    }
    // 其他pass块
}

SubShader中定义了一系列Pass以及可选的状态([RenderSteup])和标签([Tags])设置。每个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会导致渲染性能下降。所以要尽量使用最少数目的Pass。
状态和标签也可以在Pass中声明。不同的是,SubShader中的一些标签设置是特定的。SubShader中的标签设置和Pass中使用的标签是不一样的。而SubShader和Pass中状态设置的语法是相同的。
状态设置
SubShader中常见的状态设置选项

状态设置 设置命令 说明
Cull Cull Back |Front | Off 设置剔除模式:剔除背面/正面/关闭剔除
ZTest ZTest Less Greater | LEqual | GEqual | Equal | NotEqual | Always 设置深度测试时使用的函数
ZWrite ZWrite On | Off 开启/关闭深度写入
Blend Blend SrcFactor DstFactor 开启设置混合模式

如果在SubShader进行了状态的设置,那么将会应用于所有的Pass。如果不想这样,可以在Pass语义块中单独进行设置。

SubShader的标签

SubShader的标签是一对键值对(Key/Value),它的键和值都是字符串类型。这些键值对是SubShader和渲染引擎之间的沟通桥梁。它们用来告诉Unity引擎应该如何以及何时渲染这个对象。

标签的结构如下

Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

SubShader的标签类型

标签类型 说明 例子
Queue 控制渲染顺序,指定该物体属于哪一个渲染队列,通过这种方式可以保证所有的透明物体可以在所有的不透明物体后面被渲染,也可以自定义使用的渲染队列来控制物体的渲染顺序 Tags {"Queue" = "Transparent"}
RenderType 对着色器进行分类,例如这是一个不透明的着色器,或是一个透明的着色器。这可以用于着色器替换功能 Tags{"RenderType" = "Opaque" }
DisableBatching 一些SubShader在使用Unity的批处理功能时会出现问题,例如使用了模型空间下的坐标进行顶点动画。这时可以通过该标签来直接指明是否对该SubShader使用批处理 Tags{"DisableBatching" = "True"}
ForceNoShadowCasting 控制使用该SubShader的物体是否会投射阴影 Tags{"DisableNoShadowCasting" = "True"}
IgnoreProjector 如果该标签值为“True”,那么使用该SubShader的物体将不会受Projector的影响。通常用于半透明物体 Tags{"IgnoreProjector" = "True"}
CanUseSpriteAltas 当该SubShader是用于Sprite时,将该标签设置为"false" Tags{"CanUseSpriteAtlas" = "False"}
PreviewType 指明材质面板将如何预览该材质。默认情况下,材质将显示为一个球形,可以通过把该标签的值设置为"Plane"或"SkyBox"来改变预览类型 Tags{"PreviewType" = "Plane"}

以上的标签只能在SubShader语义块中声明,不可以在Pass语义块中声明,Pass中的标签不同于SubShader中的标签类型。

Pass语义块

Pass语义块的定义如下

Pass {
    [Name]
    [Tags]
    [RenderSetup]
    //Other Code
}

[Name]表示该Pass的名称,例如:Name "MyPassName"

通过这个名称,我们可以使用ShaderLab的UsePass命令来直接使其他UnityShader中的Pass,例如:UsePass "MyShader/MYPASSNAME"

由于Unity会把所有Pass的名字转换成大写字母表示,所以这里UsePass命令里Pass的名称为大写字母。

Pass也可以设置标签,其标签与SubShader的标签不同

Pass的标签类型

标签类型 说明 例子
LightMode 定义该Pass在Unity的渲染流水线中的角色 Tags{"LightMode" = "ForwardBase"}
RequireOptions 用于指定当满足某些条件时才渲染该Pass,它的值是一个由空格分隔的字符串。目前,Unity支持的选项有:SoftVegetation Tags{ "RequireOptions" = "SoftVegetation"}

 

FallBack

在各个SubShader语义块后,可以添加一个FallBack指令。如果其上的所有SubShader语义块都不能在这个显卡下运行,那么Unity执行FallBack所指定的Shader。一般FallBack中所指定的Shader为系统内置的,能被绝大多数硬件支持的。

 

CustomEditor

在ShaderLab的末尾还可以添加CustomEditor语义,可以自定义材质面板的编辑界面

(1)

本文由 树莓屋 作者:Berry贝锐 发表,转载请注明来源!

关键词:

热评文章

发表评论