Unity 有三种编写shader的方式:
surface shaders,vertex and fragment shaders,fixed function shaders.- fixed function shader (固定功能着色器): 对应于固定管线硬件的操作,最简单的着色器类型,只能使用Unity3D自带的固定语法和提供的方法,适用于任何硬件,使用难度最小。
- vertex and fragment shader (顶点片段程序着色器): 顶点和片段着色器,如前所述,是可编程图形管线主要支持的方式。是效果最为丰富的着色器类型,使用Cg/HLSL语言规范,着色器由顶点程序和片段程序组成。所有效果都需要自己编写,使用难度相对较大。
- surface shader (表面着色器): Unity推荐的shader类型。同样使用Cg/HLSL语言规范的着色器类型,不过把光照模型提取出来,可以使用Unity3D自带的一些光照模型,也可以自己编写光照模型,着色器同样由顶点程序和片段程序组成,不过本身有默认的程序方法,使用者可以只针对自己关系的效果部分进行编写。由于选择性比较大,所以可以编写出较为丰富的效果,使用难度相对vertex and fragment shader小。 可以理解其是对Vertex 和 Fragment shader的一种包装。 (surface shader有一个问题,它不支持SubShader内部的多pass,所以某些需要多pass的效果要实现起来会比较困难。)
Unity建议从ShaderLab语法开始学习shader。Fixed function shader 只能被ShaderLab编写。(但是 vertex and fragment shader 和surface shader 是不限于shaderlab的,可以使用Cg/HLSL/GLSL)。
Shaderlab基本结构
Shader "MyShader" { Properties { _MyTexture ("My Texture", 2D) = "white" { } //其他属性 } SubShader { // - surface shader or // - vertex and program shader or // - fixed function shader } SubShader { // 一个更简单的shader,可以运行在更弱的硬件上 } Fallback "Legacy Shaders/VertexLit" [CustomEditor]}
首先是一些属性定义,属性名是前面带下划线的,显示在编辑器的名字是后面字符串中的。
接下来是一个或者多个的子着色器,只有一个能被执行,哪一个子着色器被使用是由运行的平台所决定的。子着色器是代码的主体,每一个子着色器中包含一个或者多个的Pass。 最后指定一个回滚,用来处理所有Subshader都不能运行的情况(比如目标设备实在太老,所有Subshader中都有其不支持的特性)。 CustomEditor是定制编辑器。需要提前说明的是,在实际进行 surface shader 的开发时,我们将直接在Subshader这个层次上写代码,系统将把我们的代码编译成若干个合适的Pass。