ShaderLab着色器不仅仅包括“代码片段编译指令器”

ShaderLab着色器不仅仅包括“代码片段编译指令器”

ShaderLab 着色器不仅仅包括“硬件着色器”。这些着色器做很多事情。它们描述在材质检视器 (Material Inspector) 中显示的属性,容纳用于不同图形硬件的多种着色器实现,配置固定函数硬件状态等等。实际可编程着色器 - 如顶点和片元程序 - 只是整个 ShaderLab“着色器”概念的一部分。请查看着色器教程中的基本简介。在这里,我们将调用低级硬件着色器着色器程序。

如果您想编写与光照交互的着色器,请查看表面着色器文档。本页剩余部分将假设着色器不与 Unity 光照交互(例如:特殊效果、Image Effects|图像效果等。)

着色器程序的编写采用 Cg/HLSL 语言,是通过在着色器文本中 Pass 命令内的某处嵌入“代码片段”的来实现的。它们通常看起来像这样:

  Pass {
      // ...常用的通道状态设置...
      CGPROGRAM
      // 该代码片段的编译指令,例如:
      #pragma vertex vert
      #pragma fragment frag
      // Cg 代码自身
      ENDCG
      // ...通道设置的剩余部分...
  }

Cg 代码片段

Cg 程序代码片段被编写在 CGPROGRAM 和 ENDCG 之间。

在代码片段编译指令的开头,可以使用 #pragma 指令。指示编译哪些着色器函数的编译指令:

其他编译指令:

每个代码片段都必须包含一个顶点程序或一个片元程序或两者皆包含。因此,要求使用一个 #pragma vertex 指令或一个#pragma fragment 指令或两者都使用。

着色器目标

默认情况下,Unity 将着色器编译为简约 Shader Model 2.0 的相等物。使用 #pragma target 可使着色器被编译成其他能力等级。当前支持以下目标:

#pragma target 3.0 - 编译成 Shader Model 3.0: 当编译成 3.0 或更大目标时,顶点和片元程序都需要被展示。#pragma target 4.0 - 编译成 DX10 Shader Model 4.0。当前只有 DirectX 11 渲染器支持该目标。#pragma target 5.0 - 编译成 DX11 Shader Model 5.0。当前只有 DirectX 11 渲染器支持该目标。 渲染平台

Unity 支持几个渲染 API(例如,Direct3D 9 和 OpenGL),默认情况下,所有着色器程序都编译成受支持的渲染器。使用 #pragma only_renderers 或 #pragma exclude_renderers 指令,您可以指示编译成哪些渲染器。如果您知道您将只把 Mac OS X (无 Direct3D)或 Windows(Unity 默认为 D3D)作为目标unity 顶点着色器,或者如果某个特定着色器只在一个渲染器中可用,而在其他渲染器中不可用,这样是有用的。当前受支持的渲染器名称有:

例如unity 顶点着色器,以下这行指令只会将着色器编译为 D3D9 模式:

  #pragma only_renderers d3d9

着色器程序中,您通常需要访问一些全局状态,例如当前模型*视图*投影矩阵 (model*view*projection matrix)、当前环境颜色等等。无需声明这些内置状态变量,您可以直接在着色器程序中使用它们。

内置矩阵

受支持的矩阵 (float4x4):

UNITY_MATRIX_MVP
当前模型*视图*投影矩阵 (model*view*projection matrix)
UNITY_MATRIX_MV
当前模型*视图矩阵 (model*view matrix)
UNITY_MATRIX_V
当前视图矩阵 (view matrix)。
UNITY_MATRIX_P
当前投影矩阵 (projection matrix)
UNITY_MATRIX_VP
当前视图*投影矩阵 (view*projection matrix)
UNITY_MATRIX_T_MV
模型*视图矩阵 (model*view matrix) 的转置
UNITY_MATRIX_IT_MV
模型*视图矩阵 (model*view matrix) 的逆转置
UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3
纹理变换矩阵

内置向量

受支持的向量 (float4):

UNITY_LIGHTMODEL_AMBIENT
当前环境色。
 

ShaderLab 语法:Properties

着色器可以定义一系列的参数,这些参数将由 Unity 材质检视器中的设计师设定。在着色器文件中的属性 (Properties) 块定义参数。

语法 属性 (Properties) { Property [ Property ...] }

定义属性块。括号内,多个属性定义如下。

name (" display name", Range ( min, max)) = number

定义浮点属性,代表检视器中从 最小值 (min) 到 最大值 (max)的滑块。

name (" display name", Color) = ( number, number, number, number)

定义颜色属性。

name (" display name", 2D) = " name" { options }

定义二维纹理属性。

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)

定义四分量向量属性。

详细信息

着色器内部的每个属性都被名称 (name) 引用(Unity 中,着色器属性名称以下划线开头是很常见的)。在材质检视器中属性会显示为显示名称 (display name)。对每个属性来说,默认值放在等号之后:

随后在着色器中,通过使用方括号内的属性名称访问属性值:[name].

示例

Properties {
    // 水着色器的属性
    _WaveScale ("Wave scale", Range (0.02,0.15)) = 0.07 // 滑块
    _ReflDistort ("Reflection distort", Range (0,1.5)) = 0.5
    _RefrDistort ("Refraction distort", Range (0,1.5)) = 0.4
    _RefrColor ("Refraction color", Color)  = (.34, .85, .92, 1) // 颜色
    _ReflectionTex ("Environment Reflection", 2D) = "" {} // 纹理
    _RefractionTex ("Environment Refraction", 2D) = "" {}
    _Fresnel ("Fresnel (A) ", 2D) = "" {}
    _BumpMap ("Bumpmap (RGB) ", 2D) = "" {}
} 

纹理属性选项

在纹理属性的花括号内的选项 (options) 为可选项。可用选项有:

示例

// EyeLinear texgen 模式示例
Shader "Texgen/Eye Linear" {
    Properties {
        _MainTex ("Base", 2D) = "white" { TexGen EyeLinear }
    }
    SubShader {
        Pass {
            SetTexture [_MainTex] { combine texture }
        }
    }
} 

ShaderLab 语法:子着色器 (SubShader)

Unity 中的每个着色器都是由一系列的子着色器构成的。当 Unity 必须显示网格时,会找到要使用的着色器,并选择在用户显卡上运行的第一个子着色器。

语法 Subshader { [ Tags] [ CommonState] Passdef [ Passdef ...] }

定义子着色器为可选的标记、普通状态和一系列通道定义。

详细信息

子着色器定义一系列的渲染通道并视情况对所有通道设置成普通状态。此外,可以设置子着色器特定的标记。

当 Unity 选择使用哪个子着色器进行渲染时,它对每个定义的通道渲染对象一次(因为光交互也可能渲染多次)。由于每次渲染对象都是一次昂贵的操作,所以要使用尽可能最少的通道定义着色器。当然,有时在一些图形硬件上,使用一个通道不能达到需要的效果;那么您别无选择,只能使用多通道。

每个通道定义可以是一个常规通道、一个使用通道或一个捕获通道。

通道定义中允许的任何声明也可以出现在子着色器块中。这将使所有通道使用这种“共享”状态。

Example

// ...
SubShader {
    Pass {
        Lighting Off
        SetTexture [_MainTex] {}
    }
}
// ...

该子着色器定义了一个单通道游戏素材,其关闭了所有光照并只显示纹理名称为 _MainTex 的网格。

ShaderLab 语法:Pass

通道 (Pass) 块使对象的几何结构被渲染一次。

语法 Pass { [Name and Tags] [RenderSetup] [TextureSetup] }

基本通道命令包含了渲染设置命令的可选列表,后面可跟随一系列纹理以供使用。

名称和标记

通道 (Pass) 可以定义其名称和任意数量的标记 - 名称/值字符串告知渲染引擎“通道”(Pass) 的目的。

渲染设置

通道可设置图形硬件的各种状态,例如,是否应打开 alpha 混合,是否使用雾化等。其命令如下:

Material { Material Block }

定义在顶点光照管线中使用的材质。有关详细信息,请参阅 材质页面

Lighting On | Off

开启或关闭顶点光照。有关详细信息,请参阅 材质页面

Cull Back | Front | Off

设置多边形剔除模式。

ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)

设置深度测试模式。

ZWrite On | Off

设置深度编写模式。

Fog { Fog Block }

设置雾化参数。

AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue

开启 alpha 测试。

Blend SourceBlendMode DestBlendMode

设置 alpha 混合模式。

Color Color value

如果顶点光照是关闭的,则设置使用的颜色。

ColorMask RGB | A | 0 | any combination of R, G, B, A

设置颜色编写遮蔽图。编写 ColorMask 0 可关闭所有颜色通道的渲染。

Offset OffsetFactor , OffsetUnits

设置深度偏移。请注意数据报告,从 Unity 3.0 版本起,该命令只接受常量(即:非着色器参数)。

SeparateSpecular On | Off

打开或关闭顶点光照单独的高光颜色。有关详细信息,请参阅 材质页面

ColorMaterial AmbientAndDiffuse | Emission

计算顶点光照时使用逐顶点颜色。有关详细信息,请参阅 材质页面

纹理设置

渲染状态设置后,您可以应用 SetTexture 命令指定要应用的多种纹理及其组合模式:

SetTexture texture property { [Combine options] }

纹理设置可配置固定功能多层材质管线,并且如果使用自定义片段着色器,则纹理设置将被忽视。

详细信息 逐像素光照

逐像素光照管线通过在多通道中渲染对象作用。Unity 渲染对象一次以获得环境光照和所有顶点光照。然后渲染每个影响独立附加通道内的对象的像素光照。有关详细信息,请参阅渲染器管线。

逐顶点光照

逐顶点光照是对每个顶点都进行了计算的标准的 Direct3D/OpenGL 光照模式。Lighting on 可打开光照。光照受Material 块、ColorMaterial 和SeparateSpecular 令影响。有关详细信息,请参阅材质页面。

ShaderLab 内置值

Unity 为着色器提供 少量内置值:当前对象变换矩阵、时间等类似值。

使用 ShaderLab 中的内置值就像使用其他任何属性一样,唯一的区别在于您不必在某处进行声明 - 它们都是“内置的”。

在可编程着色器中使用它们需要包含UnityCG.cginc文档。

变换 float4x4 UNITY_MATRIX_MVP

当前模型*视图*投影矩阵 (model*view*projection matrix)

float4x4 UNITY_MATRIX_MV

当前模型*视图矩阵 (model*view matrix)

float4x4 UNITY_MATRIX_V

当前视图矩阵 (view matrix)。

float4x4 UNITY_MATRIX_P

当前投影矩阵 (projection matrix)

float4x4 UNITY_MATRIX_VP

当前视图*投影矩阵 (view*projection matrix)

float4x4 UNITY_MATRIX_T_MV

模型*视图矩阵 (model*view matrix) 的转置

float4x4 UNITY_MATRIX_IT_MV

模型*视图矩阵 (model*view matrix) 的逆转置

float4x4 UNITY_MATRIX_TEXTURE0 到 UNITY_MATRIX_TEXTURE3

纹理变换矩阵

float4x4 _Object2World

当前模型矩阵

float4x4 _World2Object

当前世界坐标矩阵的逆转置

float3 _WorldSpaceCameraPos

相机的世界坐标空间位置

float4 unity_Scale

xyz 组件未使用;.w 包含等比缩放对象的缩放。

光照

在普通的 ShaderLab 中,通过结尾追加零访问以下属性:例如光源的模型*光颜色是 _ModelLightColor0。在 Cg 着色器中,它们显示为单元素阵列,所以 Cg 中相同的是 _ModelLightColor[0]。

名称

类型

_ModelLightColor

float4

材质的主要*光色

_SpecularLightColor

float4

材质的高光*光色

_ObjectSpaceLightPos

float4

光源在对象空间中的位置。w 组件针对方向灯是 0,针对其他灯是 1

_Light2World

float4x4

光到世界坐标 (World) 空间矩阵

_World2Light

float4x4

世界坐标到光 (Light) 空间矩阵

_Object2Light

float4x4

对象到光 (Light) 空间矩阵

种类

文章来源:https://blog.csdn.net/andyhebear/article/details/47150153