简单示例

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{
    属性列表
}

着色器中可以定义的属性表如下:
Unity3D - Shader - ShaderLab基础语法之美_着色器

表中的“名称”指的是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) = "" {}
}

Unity3D - Shader - ShaderLab基础语法之美_着色器_02

 

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


Unity3D - Shader - ShaderLab基础语法之美_其他_03


Pass的标签类型
Unity3D - Shader - ShaderLab基础语法之美_着色器_04
渲染设置(Render Setup)

Pass里可以设置图形硬件的各种状态,例如开启Alpha混合、开启雾效等。


Pass中可用的渲染设置命令
Unity3D - Shader - ShaderLab基础语法之美_其他_05
纹理设置(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,显示声明不适用备用着色器,当没有子着色器能够运行的时候也不会有警告。