You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
533 lines
16 KiB
533 lines
16 KiB
3 years ago
|
# 前言
|
||
|
|
||
|
本编程指南仅尽可能的列出编写一个shader的参考
|
||
|
|
||
|
#
|
||
|
|
||
|
# shader编写结构
|
||
|
|
||
|
## 1.定义Properties(方便在创建材质的时候可以传入贴图等数据)
|
||
|
|
||
|
## 2.编写SubShader主题
|
||
|
|
||
|
## 2.1【Tags】
|
||
|
|
||
|
## 2.2【RenderSetUp】
|
||
|
|
||
|
### 2.2.1【LOD】渲染深度(详情参考Unity LOD 远景渲染部分)
|
||
|
|
||
|
## 2.3【GrabPass】【UsePass】【Pass】【Pass】(第二个或者其他)
|
||
|
|
||
|
----------------------案例Pass--------------------
|
||
|
【RenderSetUp】
|
||
|
CGPROGRAM
|
||
|
//编译顶点着色器
|
||
|
#pragma vertex vert
|
||
|
//编译片元着色器
|
||
|
#pragma fragment frag
|
||
|
|
||
|
### 2.3.1 其他引用以及其它编译指令
|
||
|
|
||
|
### 2.3.2 声明参数
|
||
|
|
||
|
### 2.3.3 设置应用数据->顶点着色器结构体a2v,appdata(a2v为app to vert简写)
|
||
|
|
||
|
### 2.3.4 设置顶点->片源着色器结构体v2f(v2f为vert to fragment简写)
|
||
|
|
||
|
### 2.3.5 编写顶点着色器渲染方法
|
||
|
|
||
|
v2f vert (a2v v){
|
||
|
v2f o;
|
||
|
//着色器内容
|
||
|
return o;
|
||
|
}
|
||
|
|
||
|
### 2.3.5 编写片源着色器渲染方法
|
||
|
|
||
|
fixed4 frag (v2f i) : SV_Target{
|
||
|
fixed4 tex = ...;
|
||
|
//着色器内容
|
||
|
return tex;
|
||
|
}
|
||
|
ENDCG
|
||
|
|
||
|
---------------------------------------------------
|
||
|
|
||
|
## 3.设置Fallback,如果显卡无法运行上面的SubShader,则执行FallBack预设进行渲染
|
||
|
|
||
|
# 1.Properties(参考书籍P30)
|
||
|
|
||
|
--------------------------------------------------------------------------
|
||
|
|
||
|
### 传入数据常用类型
|
||
|
|
||
|
## Int
|
||
|
|
||
|
_Int("Int",Int)=2
|
||
|
|
||
|
## Float
|
||
|
|
||
|
_Float("Float",Float)=1.0
|
||
|
|
||
|
## Range
|
||
|
|
||
|
_Range("Range",Range(0.0,5.0))=1.0
|
||
|
|
||
|
## Color
|
||
|
|
||
|
_Color("Color",Color)=(1,1,1,1)
|
||
|
|
||
|
## Vector
|
||
|
|
||
|
_Vector("Vector",Vector)=(1,1,1,1)
|
||
|
|
||
|
## 2D
|
||
|
|
||
|
_MainTex ("Texture", 2D) = "white" {}
|
||
|
ps:内置纹理名称包含white、black、gray、bump等等
|
||
|
|
||
|
## Cube
|
||
|
|
||
|
_Cubemap ("Environment Cubemap", Cube) = "_Skybox" {}
|
||
|
|
||
|
## 3D
|
||
|
|
||
|
_3D ("3D", 3D) = "black" {}
|
||
|
--------------------------------------------------------------------------
|
||
|
|
||
|
# 2.Tags(参考网站:https://gameinstitute.qq.com/community/detail/121997)
|
||
|
|
||
|
--------------------------------------------------------------------------
|
||
|
|
||
|
### 渲染类型声明(包含渲染顺序)
|
||
|
|
||
|
Tags的书写方法为键值对,可多可少,不需要全部声明,未声明时按默认值
|
||
|
Tags { "RenderType"="Opaque" "Queue"="Transparent" }
|
||
|
|
||
|
# 2.1(SubShader)Tags
|
||
|
|
||
|
## key:Queue
|
||
|
|
||
|
渲染顺序,括号内为优先度,值越小越先被渲染
|
||
|
|
||
|
## value
|
||
|
|
||
|
Background(1000)
|
||
|
Geometry(2000)【默认】
|
||
|
AlphaTest(2450)
|
||
|
Transparent(3000)
|
||
|
Overlay(4000)
|
||
|
可以自定义值例如"Queue"="3100"
|
||
|
|
||
|
## key:RenderType
|
||
|
|
||
|
渲染类型
|
||
|
|
||
|
## value
|
||
|
|
||
|
Opaque-----------------不透明(法线、自发光、反射、地形Shader)
|
||
|
Transparent------------半透明(透明、粒子、字体、地形添加通道Shader)
|
||
|
TransparentCutout------遮罩透明(透明裁切、双通道植物Shader)
|
||
|
Background-------------天空盒Shader
|
||
|
Overlay----------------GUI纹理、光晕、闪光Shader
|
||
|
TreeOpaque-------------地形引擎——树皮
|
||
|
TreeTransparentCutout--地形引擎——树叶
|
||
|
TreeBillboard----------地形引擎——公告牌(始终面向摄像机)式树木
|
||
|
Grass------------------地形引擎——草
|
||
|
GrassBillboard---------地形引擎——公告牌(始终面向摄像机)式草
|
||
|
|
||
|
## key:DisableBatching
|
||
|
|
||
|
是否禁用Batch(打包、合并)
|
||
|
|
||
|
## value
|
||
|
|
||
|
True-------------------禁用
|
||
|
False------------------不禁用(默认)
|
||
|
LODFading--------------当LOD fade开启的时候禁用,一般用在树木上面
|
||
|
|
||
|
## key:ForceNoShadowCasting
|
||
|
|
||
|
是否强制不投射阴影,当这个值为True的时候,使用这个Shader的对象便不会投射阴影。
|
||
|
|
||
|
## key:IgnoreProjector
|
||
|
|
||
|
无视投影器,当这个值为True的时候,对象便不受投射器影响。
|
||
|
|
||
|
## key:CanUseSpriteAtlas
|
||
|
|
||
|
可使用精灵集,当这个值为False的时候,不能使用精灵集。
|
||
|
|
||
|
## key:PreviewType
|
||
|
|
||
|
材质的预览形式,默认显示为球体,可以使用Plane(2D平面)或Skybox(天空盒)
|
||
|
|
||
|
# 2.2(Pass)Tags
|
||
|
|
||
|
## key:LightMode
|
||
|
|
||
|
光照模式
|
||
|
|
||
|
## value
|
||
|
|
||
|
Always------------------总是渲染,不使用光照
|
||
|
ForwardBase-------------用于前向渲染,使用环境光、主平行光、顶点/SH(球谐函数)光照以及光照贴图
|
||
|
ForwardAdd--------------用于前向渲染,额外使用每像素光,每个光照一个通道
|
||
|
Deferred----------------用于延迟着色,渲染G-Buffer
|
||
|
ShadowCaster------------渲染对象的深度到阴影贴图或者深度纹理
|
||
|
PrepassBase-------------用于(旧版)延迟光照,渲染法线和高光指数
|
||
|
PrepassFinal------------用于(旧版)延迟光照,合并贴图、光照和自发光来渲染最终色彩
|
||
|
Vertex------------------当对象不受光照贴图影响的时候,用来渲染(旧版)顶点发光。使用所有的顶点光照
|
||
|
VertexLMRGBM------------当对象接受光照贴图影响的时候,用来渲染(旧版)顶点发光。适用于使用RGBM编码光照贴图的平台(PC&主机)
|
||
|
VertexLM----------------当对象接受光照贴图影响的时候,用来渲染(旧版)顶点发光。适用于使用double-LDR编码光照贴图的平台(移动平台)
|
||
|
|
||
|
## key:PassFlags
|
||
|
|
||
|
标志渲染管线如何传递数据给通道
|
||
|
|
||
|
## value
|
||
|
|
||
|
OnlyDirectional---------只有主平行光、环境光和光照探测器的数据会传递给通道。仅用于LightMode为ForwardBase
|
||
|
|
||
|
## key:RequireOptions
|
||
|
|
||
|
标志通道至于在某些外部条件满足时才会被渲染
|
||
|
SoftVegetation----------当Quality Setting中的Soft Vegetation选项被开启时,才会渲染通道
|
||
|
|
||
|
# 3.RenderSetUp(以下写在CGPROGRAM之前)(参考书籍P31)
|
||
|
|
||
|
--------------------------------------------------------------------------
|
||
|
|
||
|
## 3.1 Cull
|
||
|
|
||
|
Cull Back | Front | Off
|
||
|
设置剔除模式:剔除背面/正面/关闭剔除
|
||
|
|
||
|
## 3.2 ZTest
|
||
|
|
||
|
ZTest Less Greater | LEqual | GEqual | Equal | NotEqual | Always
|
||
|
设置深度测试时使用的函数
|
||
|
|
||
|
## 3.3 ZWrite
|
||
|
|
||
|
ZWrite On | Off
|
||
|
开启/关闭深度写入
|
||
|
|
||
|
## 3.4 Blend
|
||
|
|
||
|
BlendOp (Op)
|
||
|
设置混合操作
|
||
|
Blend (SrcFactor) (DstFactor)
|
||
|
Blend (SrcFactor) (DstFactor),(SrcFactorA) (DstFactorA)
|
||
|
开启并设置混合模式(透明材质用)
|
||
|
例如:Blend SrcAlpha OneMinusSrcAlpha
|
||
|
|
||
|
其中SrcFactor为源颜色乘以的混合因子
|
||
|
DstFactor为目标颜色乘以的混合因子
|
||
|
两者相加存入颜色缓冲区
|
||
|
|
||
|
Blend混合操作表(参考书籍P174)
|
||
|
-----------------------------------------
|
||
|
|
||
|
Add | 源颜色和目标颜色相加
|
||
|
Sub | 源颜色减去目标颜色
|
||
|
RevSub | 目标颜色减去源颜色
|
||
|
Min | 使用目标颜色跟源颜色中较小的值
|
||
|
Max | 使用源颜色跟目标颜色中较大的值
|
||
|
|
||
|
Blend混合因子表(参考书籍P174)
|
||
|
-----------------------------------------
|
||
|
|
||
|
One | 1
|
||
|
Zero | 0
|
||
|
SrcColor | 源颜色值
|
||
|
SrcAlpha | 源颜色的透明度值
|
||
|
DstColor | 目标颜色值
|
||
|
DstAlpha | 目标颜色的透明度值
|
||
|
OneMinusSrcColor | 1-源颜色值
|
||
|
OneMinusSrcAlpha | 1-源颜色的透明值
|
||
|
OneMinusDstColor | 1-目标颜色值
|
||
|
OneMinusDstAlpha | 1-目标颜色的透明度值
|
||
|
|
||
|
常用混合类型
|
||
|
-----------------------------------------
|
||
|
|
||
|
正常--------| Blend SrcAlpha OneMinusSrcAlpha
|
||
|
柔向相加----| Blend OneMinusDstColor One
|
||
|
正片叠底----| Blend DstColor Zero
|
||
|
两倍相乘----| Blend DstColor SrcColor
|
||
|
变暗--------| BlendOp Min
|
||
|
------------| Blend One One
|
||
|
变亮--------| BlendOp Max
|
||
|
------------| Blend One One
|
||
|
滤色--------| Blend OneMinusDstColor One
|
||
|
线性减淡----| Blend One One
|
||
|
|
||
|
# 4.Pass
|
||
|
|
||
|
--------------------------------------------------------------------------
|
||
|
|
||
|
渲染所使用的通道,可以使用抓取屏幕图像的Pass--GrabPass
|
||
|
以及引用其他shader的Pass--UsePass
|
||
|
以及自己编写的Pass
|
||
|
|
||
|
# 5.vert & frag
|
||
|
|
||
|
--------------------------------------------------------------------------
|
||
|
|
||
|
顶点着色器,编写案例如下
|
||
|
需要前置结构体a2v
|
||
|
输出结构体v2f
|
||
|
(应用->顶点坐标->顶点着色器->输出顶点)
|
||
|
v2f vert (a2v v){
|
||
|
v2f o;
|
||
|
//着色器内容
|
||
|
return o;
|
||
|
}
|
||
|
|
||
|
需要前置结构体v2f
|
||
|
输出着色器颜色值fixed4
|
||
|
|
||
|
(顶点->片元着色器->输出颜色)
|
||
|
|
||
|
fixed4 frag (v2f i) : SV_Target{
|
||
|
fixed4 tex = ...;
|
||
|
//着色器内容
|
||
|
return tex;
|
||
|
}
|
||
|
|
||
|
## 5.0 结构体语义(参考书籍P110)
|
||
|
|
||
|
### a2v------从应用阶段传递模型数据给顶点着色器
|
||
|
|
||
|
| 语义 | 描述 | 类型 |
|
||
|
| ----------- | ------------------------------------------ | ------------- |
|
||
|
| POSITION | 模型空间的顶点位置 | float4 |
|
||
|
| NORMAL | 顶点法线 | float3 |
|
||
|
| TANGENT | 顶点切线 | float3 |
|
||
|
| TEXCOORD0-7 | 该顶点的纹理坐标,可以定义TEXCOORD0,TEXCOORD1表示第一组或者第二组 | float2&float4 |
|
||
|
| COLOR | 顶点颜色 | fixed4&float4 |
|
||
|
|
||
|
### v2f------从顶点着色器传递数据给片元着色器
|
||
|
|
||
|
| 语义 | 描述 | 类型 |
|
||
|
| ----------- | ----------------- | ------ |
|
||
|
| SV_POSITION | 裁剪空间中的顶点坐标 | float4 |
|
||
|
| COLOR0 | 通常用于输出第一组顶点颜色,非必需 | fixed4 |
|
||
|
| COLOR1 | 通常用于输出第二组顶点颜色,非必需 | fixed4 |
|
||
|
| TEXCOORD0-7 | 用于输出纹理坐标0-7 | 任意 |
|
||
|
|
||
|
### SV_Target------片元着色器输出时用的语义
|
||
|
|
||
|
输出值将会存储到渲染目标(Render Target)中。
|
||
|
|
||
|
### VPOS/WPOS------片元着色器传递屏幕坐标的语义
|
||
|
|
||
|
类型为float4,xy为屏幕空间中的坐标,z为近裁剪平面处于远裁剪平面处的分量,范围0-1。对于w,如果摄像机投影类型为正交投影,w恒为1,如果使用透视投影,w的取值范围为[1/Near,1/Far],Near为近裁剪平面处于摄像机的距离,Far为远裁剪平面处于摄像机的距离。
|
||
|
|
||
|
## 5.1 变换矩阵(参考书籍P87)
|
||
|
|
||
|
-----------------------------------------
|
||
|
|
||
|
### UNITY_MATRIX_MVP(取模现在被UnityObjectToClipPos(v.vertex)所替代)
|
||
|
|
||
|
当前模型的观察投影矩阵,顶点/方向矢量 模型空间->裁剪空间
|
||
|
|
||
|
### UNITY_MATRIX_MV
|
||
|
|
||
|
当前的模型观察矩阵,顶点/方向矢量 模型空间->观察空间
|
||
|
|
||
|
### UNITY_MATRIX_V
|
||
|
|
||
|
当前的观察矩阵,顶点/方向矢量 世界空间->观察空间
|
||
|
|
||
|
### UNITY_MATRIX_P
|
||
|
|
||
|
当前的投影矩阵,顶点/方向矢量 观察空间->裁剪空间
|
||
|
|
||
|
### UNITY_MATRIX_VP
|
||
|
|
||
|
当前的观察投影矩阵,顶点/方向矢量 世界空间->裁剪空间
|
||
|
|
||
|
### UNITY_MATRIX_T_MV
|
||
|
|
||
|
UNITY_MATRIX_MV的转置矩阵
|
||
|
|
||
|
### UNITY_MATRIX_IT_MV
|
||
|
|
||
|
UNITY_MATRIX_MV的逆转置矩阵,用于将发现从模型空间变换到观察空间,也可用于得到
|
||
|
UNITY_MATRIX_MV的逆矩阵
|
||
|
|
||
|
### unity_ObjectToWorld(原为_Object2World)
|
||
|
|
||
|
当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间
|
||
|
|
||
|
### unity_WorldToObject(原为_World2Object)
|
||
|
|
||
|
unity_ObjectToWorld的逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间
|
||
|
|
||
|
## 5.2 Unity内置的摄像机和屏幕参数(参考书籍P88)
|
||
|
|
||
|
-------------------------------------------------
|
||
|
|
||
|
### 【float3】 _WorldSpaceCameraPos
|
||
|
|
||
|
该摄像机在世界空间中的位置
|
||
|
|
||
|
### 【float4】 _ProjectionParams
|
||
|
|
||
|
x = 1.0 & -1.0 | y = Near | z = Far | w = 1.0 + 1.0 / Far
|
||
|
Near = 近裁剪平面到摄像机的距离
|
||
|
Far = 远裁剪平面到摄像机的距离
|
||
|
|
||
|
### 【float4】 _ScreenParams
|
||
|
|
||
|
x = width | y = height | z = 1.0 + 1.0 / width | w = 1.0 + 1.0 / height
|
||
|
width = 该摄像机的渲染目标的像素宽度
|
||
|
height = 该摄像机的渲染目标的像素高度
|
||
|
|
||
|
### 【float4】 _ZBufferParams
|
||
|
|
||
|
x = 1 - Far / Near | y = Far / Near | z = x / Far | w = y / Far
|
||
|
该变量用于线性化Z缓存中的深度值
|
||
|
|
||
|
### 【float4】unity_OrthoParams
|
||
|
|
||
|
x = width | y = height | z = 无定义 | w = 1.0(该摄像机为正交摄像机) & 0.0(该摄像机为透视摄像机)
|
||
|
width = 正交投影摄像机的宽度
|
||
|
height = 正交投影摄像机的高度
|
||
|
|
||
|
### 【float4x4】unity_CameraProjection
|
||
|
|
||
|
该摄像机的投影矩阵
|
||
|
|
||
|
### 【float4x4】unity_CameraInvProjection
|
||
|
|
||
|
该摄像机的投影矩阵的逆矩阵
|
||
|
|
||
|
### 【float4[6]】unity_CameraWorldClipPlanes[6]
|
||
|
|
||
|
该摄像机的6个裁剪平面在世界空间下的等式
|
||
|
按如下顺序:左、右、上、下、近、远裁剪平面
|
||
|
|
||
|
## 5.3 UnityCG.cginc常用的帮助函数(参考书籍P137)
|
||
|
|
||
|
-------------------------------------------------
|
||
|
|
||
|
### 【float3】 WorldSpaceViewDir(float4 v)
|
||
|
|
||
|
输入:模型空间中的顶点位置
|
||
|
返回:世界空间红从该点到摄像机的观察方向。
|
||
|
ps:内部实现使用了UnityWorldSpaceViewDir函数
|
||
|
|
||
|
### 【float3】 UnityWorldSpaceViewDir(float4 v)
|
||
|
|
||
|
输入:世界空间中的顶点位置
|
||
|
返回:世界空间中从该点到摄像机的观察方向。
|
||
|
|
||
|
### 【float3】 ObjectSpaceViewDir(float4 v)
|
||
|
|
||
|
输入:一个模型空间中的顶点位置
|
||
|
返回:模型空间中该点到摄像机的观察方向。
|
||
|
|
||
|
### 【float3】 WorldSpaceLightDir(float4 v)【仅用于前向渲染】【未被归一化】
|
||
|
|
||
|
输入:一个模型空间中的顶点位置
|
||
|
返回:世界空间中从该点到光源的光照方向。
|
||
|
ps:内部实现使用了UnityWorldSpaceLightDir函数
|
||
|
|
||
|
### 【float3】 UnityWorldSpaceLightDir(float4 v)【仅用于前向渲染】【未被归一化】
|
||
|
|
||
|
输入:世界空间中的顶点位置
|
||
|
返回:世界空间中该点到光源的光照方向
|
||
|
|
||
|
### 【float3】 ObjSpaceLightDir(float4 v)【仅用于前向渲染】【未被归一化】
|
||
|
|
||
|
输入:一个模型空间中的顶点位置
|
||
|
返回:模型空间中从该点到光源的光照方向
|
||
|
|
||
|
### 【float3】 UnityObjectToWorldNormal(float3 normal)
|
||
|
|
||
|
把法线方向从模型空间转换到世界空间中
|
||
|
|
||
|
### 【float3】 UnityObjectToWorldDir(float3 dir)
|
||
|
|
||
|
把方向矢量从模型空间变换到世界空间中
|
||
|
|
||
|
### 【float3】 UnityWorldToObjectDir(float3 dir)
|
||
|
|
||
|
把方向矢量从世界空间变换到模型空间中
|
||
|
|
||
|
# 6.关于光照
|
||
|
|
||
|
## 6.1 Unity渲染路径
|
||
|
|
||
|
------------------------------------------------------------
|
||
|
|
||
|
在tag-LightMode里设置,详情见本文2.2
|
||
|
|
||
|
## 6.2 Unity内置光照变量和函数
|
||
|
|
||
|
------------------------------------------------------------
|
||
|
|
||
|
### 【float4】 _LightColor0
|
||
|
|
||
|
该Pass处理的逐像素光源的颜色
|
||
|
|
||
|
### 【float4】 _WorldSpaceLightPos0
|
||
|
|
||
|
该Pass处理的逐像素光源的位置。
|
||
|
如果该光源是平行光,_WorldSpaceLightPos0.w=0
|
||
|
如果是其他类型光,_WorldSpaceLightPos0.w=1
|
||
|
|
||
|
### 【float4x4】 _LightMatrix0
|
||
|
|
||
|
从世界空间到光源空间的变换矩阵。可以用于采样cookie和光照衰减纹理
|
||
|
|
||
|
### 【float4】 unity_4LightPosX0 unity_4LightPosY0 unity_4LightPosZ0
|
||
|
|
||
|
仅用于BasePass
|
||
|
前四个非重要的点光源在世界空间中的位置
|
||
|
|
||
|
### 【float4】 unity_4LightPosX0 unity_4LightPosY0 unity_4LightPosZ0
|
||
|
|
||
|
仅用于BasePass
|
||
|
前四个非重要的点光源在世界空间中的位置
|
||
|
|
||
|
### 【float4】 unity_4LightAtten0
|
||
|
|
||
|
仅用于BasePass
|
||
|
前四个非重要的点光源的衰减因子
|
||
|
|
||
|
### 【half4[4]】 unity_LightColor
|
||
|
|
||
|
仅用于BasePass
|
||
|
前四个非重要的点光源的颜色
|
||
|
|
||
|
## 6.3 Unity前向渲染可以使用的内置光照参数
|
||
|
|
||
|
------------------------------------------------------------
|
||
|
|
||
|
以下函数仅用于前向渲染才可使用。
|
||
|
|
||
|
### 【float3】 WorldSpaceLightDir(float4 v)【未被归一化】
|
||
|
|
||
|
输入:一个模型空间中的顶点位置
|
||
|
返回:世界空间中从该点到光源的光照方向。
|
||
|
ps:内部实现使用了UnityWorldSpaceLightDir函数
|
||
|
|
||
|
### 【float3】 UnityWorldSpaceLightDir(float4 v)【未被归一化】
|
||
|
|
||
|
输入:一个世界空间中的顶点位置
|
||
|
返回:世界空间中从该点到光源的光照方向。
|
||
|
|
||
|
### 【float3】 ObjSpaceLightDir(float4 v)【未被归一化】
|
||
|
|
||
|
输入:一个模型空间中的顶点位置
|
||
|
返回:模型空间中从该点到光源的光照方向。
|
||
|
|
||
|
### 【float3】 Shade4PointLights(...)
|
||
|
|
||
|
输入:已经打包进矢量的光照数据,参考6.2
|
||
|
返回:计算逐顶点光照。
|