chapter2 Unity Shader概述
前言
【注】因为是概述,很多细节和需要查询的内容请参考《Unity Shader入门精要》
上一章描述了什么是渲染流水线,这一章主要讨论什么是Unity Shader。
Shader 翻译为着色器,GPU流水线中对于高度可编程的阶段来说,Shader是可以在GPU上运行的渲染代码;而对于固定流水线来说,则起着渲染设置的作用。前者有顶点着色器,片元着色器等。
正常情况下,开发者需要与下图中各种操作、文件打交道。
因为我们是在引擎上使用shader,Unity 提供了名为Unity Shader的抽象。于是我们只需要使用unity shader就可以控制所有操作。并且必要的内部功能已经写好。
与其它着色语言的关系
我们知道着色器语言主要有CG,HLSL,GLSL。
不同于它们,Unity中开发者使用的着色器语言叫做ShaderLab
,语法上shaderlab
和CG,HLSL没有太大区别,部分函数Unity没有提供;本质上shaderlab
是基于它们的封装。
虽然Unity只支持封装后的CG,HLSL,但是如果要写GLSL也是可行的(不推荐)。
Unity Shader 基本介绍
Unity Shader 结构
Unity主要有Standard Surface Shader, Unlit Shader, Image Effect Shader
以及 Compute Shader
。
Unity Shader基本结构
1 | Shader "ShaderName"{ |
Properties 声明
Properties 语义块的作用仅仅是为了让这些属性可以出现在材质面板中。
Sub Shader
真正意义上的Shader语义块都在这里面。
Tags可以进行设置
Tags{"Queue" = "Transparent"}
设置渲染顺序
Pass
Pass包含一次完整渲染流程
设置渲染状态
首先Pass的命名Name"MyPassName"
调用其他Unity Shader中的Pass
UsePass "MyShader/MyPassName"
Pass
中的Tags与SubShader中
的一样,都是用于设置渲染状态,具体的控制内容不同。
详情见《Unity Shader入门精要》P3。下图为Pass中的标签类型。
【补充】GrabPass
关键字可以将渲染结果存储到纹理中,详情参照原书。
Fall Back
FallBack "name"
,如果其它Sub
Shader都没用,就用这个指定的
FallBack off
关闭,不管了
FallBack "VertexLit"
调用内置的Shader中的Pass
结构
Unity上的着色器
表面着色器
(Surface Shader) 已经写好,开发者可编程内容少。不需要Pass包裹,引擎自行处理
本质上可以理解为顶点、片元着色器的进一步抽象,Unity中的Shader代码一般如上图所示。
1 | Shader "Custom/Simple Surface Shader"{ |
顶点/片元着色器
(Vertex/Fragment Shader)
1 | Shader "Custom/Simple VertexFragment Shader"{ |
固定函数着色器落后不讨论
从结果上来讲,Unity Shader只包含顶点片元两种可编写部分
表面着色器中SubShader
的CG代码会被Unity细分到Pass。
Unity Shader语法与语义
基础语法
1 | Shader "Unity Shaders Book/Chaper5/Simple Shader" { |
- 顶点着色器中
POSITION和SV_POSITION是CG/HLSL中的语义(semantic)不可省略。
POSITION告诉Unity将模型的坐标作为输入参数输入到v中。
而SV_POSITION则告诉Unity返回裁剪坐标。
- 片元着色器中
SV_TARGET也是一个语义,告诉系统将渲染输出存储到渲染目标,默认输出到帧缓存。(1,1,1)表示白色,这里返回了白色。
结构体用来定义着色器的输入
1 | struct a2v{ //a2v意思是将应用阶段数据传到顶点着色器 |
Unity 支持的语义有: POSITION, TANGENT, NORMAL, TEXCOORDO, TEXCOORDJ, TEXCOORD2, TEXCOORD3, COLOR 等。
struct StructName{TypeName name : Semantic;};
顶点与片元着色器通信
1 | struct v2f{ //从顶点着色器到片元 |
以下为完整代码
1 | Shader "Unity Shaders Book/Simple Shader"{ |
属性
1 | Properties{ |
区别ShaderLab和CG的变量
文件
已知真正的Shader不是简单的一个.shader
文件。
UnityShader 的方便性使得不用开发者自己转换法线方向,处理光照阴影等。
类似于C++的头文件,写在CG中,根据情况下载
1 | CGPROGRAM |
Debug
ColorPicker.cs绑定摄像机,获取屏幕RGB值
其他
有关CG/HLSL的语义,可参照微软DX文档
语义主要是用来限定输入输出的字符串,决定输入输出来源去向,方式等。
SV(system value semantics)
定义复杂变量类型时,需要注意,一个语义,寄存器只能存储4个浮点数,所以可以采取分成4个变量表示一个矩阵
【注意】shader中不要除以0,会造成意想不到的错误。