常用Shader寫法-1
聲明標(biāo)簽:
[Header(分組名)]:分組并定義分組名
[Enum(CustomEnum1,1,CustomEnum2,2)]:枚舉,類型為float
[IntRange]:將Range變量的調(diào)整范圍改為整數(shù)
[Toggle]:在聲明shader的float變量時(shí),添加此聲明可轉(zhuǎn)換為勾選,默認(rèn)值為(0,1)。計(jì)算時(shí)實(shí)現(xiàn)效果可使用lerp方法。
[MaterialToggle]:在聲明shader的float變量時(shí),添加此聲明可轉(zhuǎn)換為勾選,默認(rèn)值為(0,1)。計(jì)算時(shí)實(shí)現(xiàn)效果可使用lerp方法。
[HDR]:在聲明shader的Color變量時(shí),添加此聲明可將顏色更換為HDR模式
[Space(int值,省略默認(rèn)為1)]:空間劃分間隔
Range(0, 1):在聲明shader的float變量時(shí),將float替換為Range(min,max)可實(shí)現(xiàn)滑塊效果

一些內(nèi)置枚舉,參考:
[Header(Option)]
[Enum(UnityEngine.Rendering.BlendOp)]? _BlendOp? ("BlendOp", Float) = 0
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("SrcBlend", Float) = 1
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("DstBlend", Float) = 0
[Enum(Off, 0, On, 1)]_ZWriteMode ("ZWriteMode", float) = 1
[Enum(UnityEngine.Rendering.CullMode)]_CullMode ("CullMode", float) = 2
[Enum(UnityEngine.Rendering.CompareFunction)]_ZTestMode ("ZTestMode", Float) = 4
[Enum(UnityEngine.Rendering.ColorWriteMask)]_ColorMask ("ColorMask", Float) = 15
[Header(Stencil)]
[Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp ("Stencil Comparison", Float) = 8
[Enum(UnityEngine.Rendering.StencilOp)]_StencilPass ("Stencil Pass", Float) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilFail ("Stencil Fail", Float) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilZFail ("Stencil ZFail", Float) = 0

方法:
Round:四舍五入
Clamp:限制大小
Muitply:相乘
dot():點(diǎn)乘
mul():相乘
lerp(x, y, z):插值。z為0則x,z為1則y。
reflect(x,y):基于向量y得到向量x的反射向量
pow(x,y):x的y次方
max(x,y):取x與y中更大的值

API:
UnityObjectToClipPos():傳入頂點(diǎn),傳出裁剪空間頂點(diǎn),用SV_POSITION存儲(chǔ)。
UnityObjectToWorldNormal():傳入法線,輸出世界空間法線,用TEXCOORD存儲(chǔ)。
unity_ObjectToWorld:矩陣,可用于轉(zhuǎn)換頂點(diǎn)到世界空間下,用mul相乘。
_WorldSpaceCameraPos:世界空間攝像機(jī)坐標(biāo)。
_WorldSpaceLightPos0:世界空間燈光向量。

公式:
蘭伯特:
模型法線乘以光的反方向并歸一化。
半蘭伯特:
模型法線乘以光的反方向并乘以0.5再加上0.5。
Phong高光:
光方向與模型法線進(jìn)行reflect得到光的反射方向后,點(diǎn)乘視角方向,得到高光。
BlinnPhong高光:
光方向乘以視角方向歸一化的值,乘以法線得到Blinn高光。
Ramp貼圖:
將蘭伯特的值作為u坐標(biāo),再傳入一個(gè)v坐標(biāo),合并作為貼圖的uv。
屏幕空間貼圖:
屏幕空間坐標(biāo)轉(zhuǎn)貼圖uv。
屏幕空間貼圖(可縮放):
屏幕空間坐標(biāo)乘以深度的積轉(zhuǎn)貼圖uv。
網(wǎng)點(diǎn)效果:
屏幕坐標(biāo)乘以縮放變量(也可繼續(xù)乘以深度)后,取余,將0~1的值映射到-0.5~0.5,再取點(diǎn)的長(zhǎng)度,可得程序化網(wǎng)點(diǎn)遮罩。(可用round使網(wǎng)點(diǎn)有清晰邊緣)
環(huán)境光:
環(huán)境光可以通過(guò)給一個(gè)顏色來(lái)偽裝環(huán)境光,具體實(shí)現(xiàn)方法:
上環(huán)境光可以通過(guò)法線的g通道得到
下環(huán)境光可以通過(guò)法線的g通道的負(fù)值得到
中間環(huán)境光可以通過(guò)1減上環(huán)境光減去下環(huán)境光得到
各個(gè)值歸一化乘以顏色相加,得到環(huán)境光。
法線貼圖:
輸入結(jié)構(gòu)添加TANGENT(切線),輸出結(jié)構(gòu)添加法線、切線、副切線,在頂點(diǎn)著色器計(jì)算三個(gè)線,在片元著色器通過(guò)UnpackNormal(tex2D(貼圖,uv))轉(zhuǎn)換法線貼圖,將法線、切線、副切線合成為float3x3(切線、副切線、法線)結(jié)構(gòu),乘以貼圖后的值,替換蘭伯特光照的法線,得到法線效果。
TBN = Tangent BiTangent Normal =?float3x3(切線、副切線、法線)
傳入一個(gè)v,包含模型基礎(chǔ)信息。
normal = UnityObjectToWorldNormal(v.normal);
tangentDir = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz);
bitangentDir = normalize(cross(normal, tangentDir) * v.tangent.w);

菲涅爾效果:
模型法線點(diǎn)乘視角方向,再被1減去,得到菲涅爾效果。
頂點(diǎn)著色器中要將頂點(diǎn)轉(zhuǎn)化到世界空間,片元著色器中可用攝像機(jī)坐標(biāo)減去頂點(diǎn)坐標(biāo)得到視角方向。
頂點(diǎn)轉(zhuǎn)換到世界空間,可將頂點(diǎn)坐標(biāo)添加一個(gè)值作為四維數(shù),乘以矩陣?unity_ObjectToWorld?得到世界空間頂點(diǎn)。
攝像機(jī)坐標(biāo)可用?_WorldSpaceCameraPos.xyz?獲得
模型法線的綠通道乘以菲涅爾,可得到上下的菲涅爾效果。
Matcap貼圖:
一種仿PBR效果的方式,可以有效節(jié)約資源,缺點(diǎn)是不適合動(dòng)態(tài)物體。
世界空間法線與矩陣?UNITY_MATRIX_V?相乘,得到屏幕空間法線。將得到的三維數(shù)取x和y,乘以0.5加0.5,得到的值作為取樣貼圖的uv,即可得到效果。
Mip貼圖:
一種仿反射天空效果的貼圖方式。
聲明Cube格式的貼圖,再聲明一個(gè)float作為L(zhǎng)OD(模糊程度)
頂點(diǎn)著色器中要將頂點(diǎn)轉(zhuǎn)化到世界空間,片元著色器中可用攝像機(jī)坐標(biāo)減去頂點(diǎn)坐標(biāo)得到視角方向。
頂點(diǎn)轉(zhuǎn)換到世界空間,可將頂點(diǎn)坐標(biāo)添加一個(gè)值作為四維數(shù),乘以矩陣?unity_ObjectToWorld?得到世界空間頂點(diǎn)。
攝像機(jī)坐標(biāo)可用?_WorldSpaceCameraPos.xyz?獲得
再通過(guò)reflect得到負(fù)的視角方向基于法線的反射方向(視角方向?yàn)橐阅P晚旤c(diǎn)為起點(diǎn),攝像機(jī)方向的矢量。它的負(fù)值即將方向變?yōu)榉聪?,從攝像機(jī)到頂點(diǎn))
得到的反射為float3,再添上聲明的LOD作為float4,合并的值通過(guò)
texCUBElod(Mip貼圖,合并的float4) 取得顏色得到結(jié)果。
陰影:
編寫前須引入4個(gè)庫(kù):
#include "UnityCG.cginc"
#include "AutoLight.cginc"
#include "Lighting.cginc"
#pragma multi_compile_fwdbase
輸入到裁剪空間的頂點(diǎn)坐標(biāo)要固定名稱為pos。
輸出結(jié)構(gòu)內(nèi)要聲明
LIGHTING_COORD(X,Y)(x和y代指TEXCOORDX和TEXCOORDY)
頂點(diǎn)著色器中將坐標(biāo)轉(zhuǎn)換裁剪空間后,執(zhí)行方法:
TRANSFER_VERTEX_TO_FRAGMENT(傳出的值)
在片元著色器中取float值:LIGHT_ATTENUATION(傳入值),乘以顏色即可。