Shader初学者的学习笔记
第一天 Unity Shader的结构
文章目录
- Shader初学者的学习笔记
- 前言
- 一、Unity Shader结构
- 二、Unity Shader结构解析
- ① Properties
- ② Tags
- ③ RenderSetup(可选状态)
- ④ Name
- ⑤ [Tags]
- ⑥ [RenderSetup]
- ⑦ 顶点着色器和片元着色器的代码 (Unity最聪明的孩子)
- ⑧ Fallback
- 总结
前言
由于看完Unity Shader入门精要后发现自己看了就忘,于是想着写博客来记录一下入门精要这本书里面的我觉得需要记录的内容,如果学的比较扎实的话,之后会对一些好的Shader进行学习,每天一篇
一、Unity Shader结构
Shader "Shader name"
{Properties{Name ("display name", propertyType) = DefaultValue ①}SubShader{[Tags] ②[RenderSetUp] ③Pass{[Name] ④[Tags] ⑤[RenderType] ⑥//顶点着色器和片元着色器 ⑦}}SubShader{...}FallBack "Diffuse" ⑧
}
二、Unity Shader结构解析
① Properties
Properties语义块中包含了一系列的属性,这些属性会出现在材质面板中;
Name ("display name", PropertyType) = DefaultValue
EX:
//单独的数字
_Int ("Int", Int) = 2
_Float ("Float", Float) = 1.5
_Range ("Range", Range(1.0, 5.0)) = 3.0
//四维向量
_Color ("Color", Color) = (1, 1, 1, 1)
_Vector ("Vector", Vector) = (2, 3, 6, 1);
//Textures 纹理类型的属性定义稍微复杂,默认值嘶通过一个字符串后跟一个花括号来指定的,字符串里面要么是空,要么是内置的纹理名称:white, black
_2D ("2D", 2D) = "" {}
_Cube ("Cube", Cube) = "white" {}
_3D ("3D", 3D) = "black" {}
Name:如果我们需要在Shader中访问这些属性,就需要使用各个属性的名字;
display name则是出现在材质面板上的名字
PropertyType指定了属性的类型
② Tags
Tags {"TagName1" = "Value1", "TagName2" = "Value2"}
标签类型 | 说明 |
---|---|
Queue | 控制渲染顺序,指定该物体属于哪个渲染队列,通过这种方式可以保证所有的透明物体可以在所有不透明物体的后面被渲染 |
RenderType | 对着色器进行分类,例如这是一个不透明的着色器,或是一个透明的着色器,这可以被用于着色器替换功能 |
DisableBatching | 一些SubShader在使用Unity的批处理功能时会出现问题,例如使用了模型空间下的坐标进行顶点动画,这是可以通过该标签来直接指明是否对该SubSahder使用批处理 |
ForceNoShadowCastingCasting | 控制使用该SubShader的物体是否会投射阴影 |
IgnoreProjector | 如果该标签为True,那么使用该SubShader的物体将不会受Projector的影响,通常用于半透明物体 |
注意:以上的这些标签之恩在SubShader中声明,但是不能在Pass中声明
③ RenderSetup(可选状态)
状态名称 | 设置指令 | 解释 |
---|---|---|
Cull | Cull Back /Front/ OFF | 设置剔除模式;剔除背面/正面/关闭剔除 |
ZTest | ZTest Less Greater/ LEqual? GEqual / NotEqual/ Always | 设置深度测试时使用的函数 |
ZWrite | ZWrite On / Off | 开启/ 关闭深度写入 |
Blend | Blend SrcFactor DscFactor | 开启并设置混合模式 |
注意:如果在SubShader里面设置了渲染状态后,将会应用到所有的Pass,如果我们不想这样,可以在Pass语义块中单独进行上面的设置
④ Name
我们可以在Pass中单独定义该Pass的名称,通过这个名称,我们可以使用UsePass命令来直接使用其他的Unity Shader中的Pass,但是需要注意的是:由于Unity内部会把所有的Pass的名称转化为大写字母的表示.因此,使用UsePass命令时必须使用大写形式的名字.
Ex:
UsePass "MyShader/MYPASSNAME
⑤ [Tags]
我们在上面说过,SubShader中的Tags与此处的标签不同:此处的这些标签也用于告诉渲染引擎我们希望怎样渲染该物体
标签类型 | 说明 |
---|---|
LightMode | 定义该Pass在Unity的渲染流水线中的角色 |
RquireOptions | 用于指定当满足某些条件时才能渲染该Pass,它的值是一个用空格分隔的字符串 |
⑥ [RenderSetup]
我们在上面也说过,如果需要单独设置每一个Pass的渲染状态,就可以不用在SubShader中设置渲染状态,例如:在进行双面渲染时,我们希望在第一个Pass中剔除正面来对背面渲染,在第二个Pass中剔除背面来对正面进行渲染,这是就应该在Pass语义块中进行单独设置.因此这块的状态名称与SubShader里面的状态名称是共用的.
⑦ 顶点着色器和片元着色器的代码 (Unity最聪明的孩子)
在今天这一部分我们先不介绍顶点着色器和片元着色器,因为会在之后着重介绍,其实除了这两个着色器之外,还有表面着色器等,由于我们在这本书中着重讲的是顶点着色器和片元着色器,所以这块就这样写.
顶点着色器要做的事情就是将在模型空间的顶点,先转换到模型空间,在变换到观察空间,经过裁剪空间的计算,对裁剪平面的图元进行剔除,保留裁剪空间内的图元.
一句话总结:
顶点着色器的最基本的任务就是把顶点坐标从模型空间转换到裁剪空间中(逐顶点).
在片元着色器中,我们通常也可以得到该片元在屏幕空间的像素位置(逐片元).
⑧ Fallback
在每一个SubShader语义块的后面,可以是一个Fallback命令,它用于告诉Unity,如果上面的所有SubShader在这块显卡上都不能运行,那么就用这个低级的shader吧!!!
事实上,Fallback还会影响阴影的投射,在渲染阴影纹理时,Unity会在每一个Unity Shader中寻找一个阴影投射的Pass,通常情况下,我们不需要自己专门实现一个Pass,这是因为Fallback使用的内置Shader中包含这样一个通用的Shader,因此,为每一个Unity Shader正确设置Fallback是非常重要的.
总结
以上就是今天我总结的内容了,就是将Unity Shader的大致结构进行一个分析理解,方便之后对代码的学习理解.