Unity3D - Shader - ShaderLab基础语法

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的意图,他是“键值对”的形式。

渲染设置(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种:

  1. combine:将两种颜色混合,混合的源可以是previous(上一次SetTexture的结果)、constant(常量颜色值)、primary(顶点颜色)、texture(纹理颜色)的一种。
  2. constantColor:设置一个常量颜色值。
  3. matrix:设置矩阵对纹理坐标进行变换

另外,Unity中还可以使用两种特殊的Pass来重用一些常用的功能,或者实现一些高级特效。

  1. UsePass:可以通过UsePass来重用其他着色器中命令的Pass。例如:

    UsePass "Specular/BASE" // 使用高光着色器Specular中命名为Base的pass

  2. GrabPass:将屏幕抓取到一个纹理中,供后续的Pass使用,可以通过GrabTexture来访问。

Fallback备用着色器

Fallback语句一般位于所有子着色器之后。
Fallback语句的用法有两种:

  1. Fallback”备用着色器名称”,例如Fallback “Diffuse”
  2. Fallback Off,显示声明不适用备用着色器,当没有子着色器能够运行的时候也不会有警告。
相关文章

相关标签/搜索