Unity3D Shader学习之六—顶点和片段着色器

基于上一篇文章的内容,将重点放在顶点和片段着色器。

下面是顶点和片段着色器的基本结构:

各部分详细说明:

Name:
Shader “name{ [Properties] Subshaders [Fallback] } 定义一个着色器
可以支持/,在编辑中以目录的形式展示,例如:

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)定义四分量向量属性。

如果您想在着色器程序中访问那些属性中的一些属性,您需要声明一个具有相同名称和匹配类型的 Cg/HLSL 变量。例如,以下这些着色器属性:

将在 Cg/HLSL 代码中被声明为:

SubShader:
Subshader { [Tags] [CommonState] Passdef [Passdef …] }定义子着色器为可选的标记、普通状态和一系列通道定义。

Pass:
Pass { [Name and Tags] [RenderSetup] [TextureSetup] }基本通道命令包含了渲染设置命令的可选列表,后面可跟随一系列纹理以供使用。
Pass结构是这样的,Cg 程序代码片段被编写在 CGPROGRAMENDCG 之间。

FallBack:
Fallback”name”回退到有给定名称的着色器。
Fallback Off 回退关闭,明确表示即使没有子着色器可以在该硬件上运行,也不会有回退以及应打印的警告。

顶点着色器示例:

看示例中的蓝色部分:

1.#pragma vertex vert

#pragma指令,指定vertex函数为vert,常用的指令有:

  • #pragma vertex 名称 – 将函数名称编译为顶点着色器。
  • #pragma fragment 名称 – 将函数名称编译为片元着色器。
  • #pragma geometry 名称 – 将函数名称编译为 DX10 几何结构着色器。要使这个选项自动打开 #pragma target 4.0
  • #pragma hull 名称 – 将函数名称编译为 DX11 外壳着色器。要使这个选项自动打开 #pragma target 5.0
  • #pragma domain 名称 – 将函数名称编译为 DX11 域着色器。要使这个选项自动打开 #pragma target 5.0

2.#include “UnityCG.cginc”
Unity可包含引入预定义变量和帮助函数的文件,其他内置文件有:

  • HLSLSupport.cginc– (自动包含) 用于跨平台着色器编译的帮助宏和定义。
  • UnityCG.cginc– 常用的全局变量和帮助函数。
  • AutoLight.cginc– 光照和阴影功能,例如,表面着色器在内部使用此文件。
  • Lighting.cginc– 标准表面着色器光照模型;当您编写表面着色器时自动将其包含。
  • TerrainEngine.cginc– 用于地形 (Terrain) 和植被 (Vegetation) 着色器的帮助函数。

3.appdata_base

是一个数据结构,提供顶点数据给 Cg/HLSL 顶点程序,几个常用的顶点结构定义在UnityCG.cginc 包含文件,大多数情况下只使用它们就足够了。其它结构有:

  • appdata_base: 顶点由位置、法线和一个纹理坐标构成。
  • appdata_tan: 顶点由位置、切线、法线和一个纹理坐标构成。
  • appdata_full: 顶点由位置、切线、法线、两个纹理坐标以及颜色构成

结构成员必须是下面列出的成员:
float4 vertex 是顶点位置
float3 normal 是顶点法线
float4 texcoord 是第一个 UV 坐标
float4 texcoord1 是第二个 UV 坐标
float4 tangent 是切线向量(用于法线贴图)
float4 color 是逐顶点颜色

顶点着色器是如何知道这些成员的含义的呢?是由成员定义时后跟冒号加字符串指定的!这些字符串就是语义。例如appdata_base定义如下(请查看UnityCG.cginc源文件):

4.SV_POSITION,COLOR0
上面提到了语义,SV_POSITION也是语义。但这个是顶点到片段着色器的语义。顶点到片段着色器的语义列表:

5.UNITY_MATRIX_MVP

Unity 内置的空间变换矩阵,位于HLSLSupport.cginc,上面提到了是自动包含的,所以着色器可以直接使用。其他变换矩阵及其含义,在下一篇会详细介绍!

要想了解每个部分的详细含义及内容,请查看官方文档。