Unity Shader 內建指令&標籤
===
1.Properties中的特殊命令
---
<table>
<thead>
<tr>
<th>命令</th>
<th>參數</th>
<th>說明</th>
</tr>
</thead>
<tr>
<td>[Header(content)]</td>
<td>括號內為頭標題的顯示文字</td>
<td>content為不用加引號的字串,不支援中文</td>
</tr>
<tr>
<td>[NoScaleOffset]</td>
<td></td>
<td>隱藏貼圖的Tilling和Offset選項</td>
</tr>
<tr>
<td>[Toggle]</td>
<td></td>
<td>模擬開關,0為false,1為true,與[MaterialToggle]相同</td>
</tr>
</table>
<br>
2.SubShader區塊中的渲染狀態設置指令
---
<table>
<thead>
<tr>
<th>指令</th>
<th>參數</th>
<th>說明</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cull</td>
<td>Cull Back/Front/Off</td>
<td>剔除模式</td>
</tr>
<tr>
<td>ZTest</td>
<td>ZTest Less/Greater/Equal/LEqual/GEqual/NotEqual/Always</td>
<td>深度測試</td>
</tr>
<tr>
<td>ZWrite</td>
<td>ZWrite On/Off</td>
<td>深度寫入</td>
</tr>
<tr>
<td>Blend</td>
<td>Blend xx (下方詳細說明)</td>
<td>顏色混合模式</td>
</tr>
</tbody>
</table>
<br>
Blend 包含以下幾種方式:
<ul>
<li> Blend Off <br>
關閉顏色混合模式,默認值
<li> Blend {SrcFactor} {DstFactor} <br>
最終顏色 = SrcFactor * 源顏色(計算出來的片源顏色) + DstFactor*目標顏色(顏色緩衝區中的顏色)
<li> Blend SrcFactor DstFactor, SrcFactorA DstFactorA <br>
與上一點相似,只是把Alpha通到分離出來 <br>
上述SrcFactor與DstFactor的值可以為以下任一個值:
<table>
<thead>
<tr>
<th>指令</th>
<th>值</th>
</tr>
</thead>
<thead>
<tr>
<td>One</td>
<td>1</td>
</tr>
<tr>
<td>Zero</td>
<td>0</td>
</tr>
<tr>
<td>SrcColor</td>
<td>源顏色</td>
</tr>
<tr>
<td>SrcAlpha</td>
<td>源透明度</td>
</tr>
<tr>
<td>DstColor</td>
<td>目標顏色</td>
</tr>
<tr>
<td>DstAlpha</td>
<td>目標透明度</td>
</tr>
<tr>
<td>OneMinusSrcColor</td>
<td>1 - 源顏色</td>
</tr>
<tr>
<td>OneMinusSrcAlpha</td>
<td>1 - 源透明度</td>
</tr>
<tr>
<td>OneMinusDstColor</td>
<td>1 - 目標顏色</td>
</tr>
<tr>
<td>OneMinusDstAlpha</td>
<td>1 - 目標透明度</td>
</tr>
</tbody>
</table>
<li> Blend Op <br>
採用操作符進行計算<br>
<table>
<tr>
<td>指令</td>
<td>值</td>
</tr>
<tr>
<td>Add</td>
<td>源顏色 + 目標顏色</td>
</tr>
<tr>
<td>Sub</td>
<td>源顏色 - 目標顏色</td>
</tr>
<tr>
<td>RevSub</td>
<td>目標顏色 - 源顏色</td>
</tr>
<tr>
<td>Min</td>
<td>取源顏色和目標顏色中的較小的</td>
</tr>
<tr>
<td>Max</td>
<td>取源顏色和目標顏色中的較大者</td>
</tr>
</table>
<li> Blend OpColor,OpAlpha <br>
與4相似,只是把透明通道分離出來
</ul>
3.SubShader區塊的Tag標籤
<table>
<tr>
<td>標籤類型</td>
<td>值</td>
<td>說明</td>
</tr>
<tr>
<td>Queue</td>
<td>Background/Geometry/AlphaTest/Transparent/Overlay</td>
<td>對應值為1000/2000/2450/3000/4000</td>
</tr>
<tr>
<td>RenderType</td>
<td>
Opaque/Transparent/TransparentCutout/Background/Overlay/<br>
TreeOpaque/TreeTransparentCutout/TreeBillboard/Grass/GrassBillboard
</td>
</tr>
<tr>
<td>DisableBatching</td>
<td>true/false</td>
<td>禁用批處理</td>
</tr>
<tr>
<td>ForceNoShadowCasting</td>
<td>true/false</td>
<td>禁止投影陰影</td>
</tr>
<tr>
<td>IgnoreProjector</td>
<td>true/false</td>
<td>忽略Projector,通常用於半透明物體</td>
</tr>
<tr>
<td>CanUseSpriteAtlas</td>
<td>true/false</td>
<td>當該SubShader用於Sprite時用false</td>
</tr>
<tr>
<td>PreviewType</td>
<td>Plane/SkyBox</td>
<td>預覽形狀</td>
</tr>
</table>
3.Pass區塊中的指令
---
<ul>
<li> Name "MYPASSNAME" <br>
為該Pass命名,用於在其它Shader中通過UsePass命令調用該Pass,即使使用小寫字母命名,Unity也會自動轉為大寫字母,所以UsePass命令中也需寫成大寫字母
<li> GrabPass { "TextureName" } <br>
抓取屏幕並生成紋理,TextureName為自定義紋理名稱,默認為_GrabTexture
</ul>
4.Pass區塊中的Tag標籤
---
<table>
<tr>
<td>標籤類型</td>
<td>值</td>
<td>說明</td>
</tr>
<tr>
<td>LightMode</td>
<td>Always/ForwardBase/ForwardAdd/Deferred/ShadowCaster/<br>
MotionVectors/PrepassBase/PrepassFinal/Vertex/VertexLMRBM/VertexLM
</td>
<td>詳見官方文檔</td>
</tr>
<tr>
<td>PassFlags</td>
<td>OnlyDirectional</td>
<td>僅傳送主平行光、環境光和LightProbe的光照數據</td>
</tr>
<tr>
<td>RequireOptions</td>
<td>SoftVegetation</td>
<td>滿足給定條件才渲染該Pass</td>
</tr>
</table>
5.#pragma指令
---
<table>
<tr>
<td>指令</td>
<td>值</td>
<td>說明</td>
</tr>
<tr>
<td>target</td>
<td>
2.0/2.5(default)/3.0/3.5(es3.0)/ <br>
4.0/4.5(es3.1)/4.6(gl4.1)/5.0
</td>
<td></td>
</tr>
<tr>
<td>geometry</td>
<td></td>
<td>用於geometry shader,編譯目標自動設為4.0</td>
</tr>
<tr>
<td>hull</td>
<td></td>
<td>用於tessellation shader,編譯目標自動設為4.6</td>
</tr>
<tr>
<td>domain</td>
<td></td>
<td>同hull</td>
</tr>
<tr>
<td>vertex</td>
<td>頂點函數名</td>
<td>定義頂點函數入口</td>
</tr>
<tr>
<td>fragment</td>
<td>片元函數名</td>
<td>定義片元函數入口</td>
</tr>
<tr>
<td>only_renderers</td>
<td>d3d9/d3d11/opengl/gles/xbox360/p3/flash</td>
<td>指定渲染平台</td>
</tr>
<tr>
<td>exclude_renderers</td>
<td>同only_renderers</td>
<td>排除指定平台</td>
</tr>
<tr>
<td>multi_compile_fwdadd_fullshadows</td>
<td></td>
<td>開啟ForwardAdd中的陰影效果</td>
</tr>
<tr>
<td>multi_compile_fwdbase</td>
<td></td>
<td>用於ForwardBase,保證光照衰減等光照變量被正確賦值</td>
</tr>
<tr>
<td>multi_complie_fwdadd</td>
<td></td>
<td>用於ForwardAdd,保證光照衰減等光照變量被正確獲取</td>
</tr>
</table>
6.Unity內置函數
---
<table>
<tr>
<td>函數</td>
<td>說明</td>
</tr>
<tr>
<td>float UnityObjectToClipPos(float3 pos)</td>
<td>將頂點座標從模型空間轉換到剪裁空間</td>
</tr>
<tr>
<td>float3 UnityObjectToViewPos(float3 pos)</td>
<td>將頂點座標從模型空間轉換到觀察空間</td>
</tr>
<tr>
<td>TRANSFORM_TEX(tex,name)(tex.xy * name##_ST.xy+name##_ST.zw)</td>
<td>根據貼圖的tilling和offset值計算uv,需要定義變量"貼圖名稱_ST",例:_MainTex_ST</td>
</tr>
<tr>
<td>ComputeScreenPos(float4 pos)</td>
<td>計算頂點再屏幕(螢幕)空間的位置</td>
</tr>
<tr>
<td>float3 WorldSpaceViewDir(float4 v)</td>
<td>輸入頂點為置,輸出世界空間下頂點到攝影機的方向</td>
</tr>
<tr>
<td>float3 UnityWorldSpaceViewDir(float4 v)</td>
<td>輸入一個世界頂點,輸出世界空間下該點到攝影機的方向</td>
</tr>
<tr>
<td>float3 ObjSpaceViewDir(float4 v)</td>
<td>輸入頂點為置,輸出模型空間下頂點到攝影機的方向</td>
</tr>
<tr>
<td>float3 WorldSpaceLightDir(float4 v)</td>
<td>僅用於前像渲染,輸入頂點位置,輸出世界空間下頂點到光源的方線</td>
</tr>
<tr>
<td>float3 UnityWorldSpaceLightDir(float4 v)</td>
<td>僅用於前像渲染,輸入一個世界座標,輸出世界空間下該點到光源的方向</td>
</tr>
<tr>
<td>float3 ObjSpaceLightDir(float4 v)</td>
<td>僅用於前像渲染,輸入頂點位置,輸出模型空間下頂點到光源的方向</td>
</tr>
<tr>
<td>float3 UnityObjectToWorldNormal(float3 norm)</td>
<td>將法線方向從模型空間轉換到世界空間</td>
</tr>
<tr>
<td>float3 UnityObjectToWorldDir(in float3 dir)</td>
<td>將方向從模型空間轉換到世界空間</td>
</tr>
<tr>
<td>float3 UnityWorldToObjectDir(float3 dir)</td>
<td>將方向從世界空間轉換到模型空間</td>
</tr>
<tr>
<td>SHADOW_COORDS(i)</td>
<td>
放在ForwardBase渲染路徑下頂點函數的輸出結構體中,需引用"AutoLight.cginc",i是可用寄存器索引 <br>
用於聲明應影紋理的座標
</td>
</tr>
<tr>
<td>TRANSFER_SHADOW(o)</td>
<td>計算結果即為陰影紋理的座標,o為輸出結構體,須放在頂點函數中</td>
</tr>
<tr>
<td>SHADOW_ATTENUATION(i)</td>
<td>
計算陰影衰減值,須放在片元函數中,i為片元函數的輸入結構體,即上式中的o <br>
注意:以上三個函數使用時,須保證頂點函數的輸入結構體變量為v,結構體的頂點座標為vertex,輸出結構體中的頂點座標為pos
</td>
</tr>
<tr>
<td>float2 ParallaxOffset(half h, half height, half3 viewDir)</td>
<td>為視差法線貼圖計算UV偏移</td>
</tr>
<tr>
<td>fixed Luminance(fixed3 c)</td>
<td>將顏色轉換為亮度(灰度)</td>
</tr>
<tr>
<td>fixed3 DecodeLightmap(fixed4 color)</td>
<td>從Unity光照貼圖解碼顏色(基於平台為RGBM或dLDR)</td>
</tr>
<tr>
<td>float4 EncodeFloatRGBA(float v)</td>
<td>為儲存低精度的渲染目標,編碼(0..1)範圍的符點數道RGBA顏色</td>
</tr>
<tr>
<td>float DecodeFloatRGBA(float4 enc)</td>
<td>解碼RGBA顏色到float</td>
</tr>
<tr>
<td>float2 EncodeFloatRG(float v)</td>
<td>類似EncodeFloatRGBA</td>
</tr>
<tr>
<td>float DecodeFloatRG(float2 enc)</td>
<td>類似DecodeFloatRGBA</td>
</tr>
<tr>
<td>float2 EncodeViewNormalStereo(float3 n)</td>
<td>編碼視圖空間法線到在0到1範圍的兩個數</td>
</tr>
<tr>
<td>float3 DecodeViewNormalStereo(float4 enc4)</td>
<td>從enc4.xy解碼視圖空間法線</td>
</tr>
</table>
7.Unity內置變數
---
<table>
<tr>
<td>UNITY_MATRIX_MVP</td>
<td>將頂點/方向從模型空間轉換到剪裁空間</td>
</tr>
<tr>
<td>UNITYMATRIX_MV</td>
<td>將頂點/方向從模型空間轉換到觀察空間</td>
</tr>
<tr>
<td>UNITY_MATRIX_V</td>
<td>將頂點/方向從世界空間轉換到觀察空間</td>
</tr>
<tr>
<td>UNITY_MATRIX_P</td>
<td>將頂點/方向從觀察空間轉換到剪裁空間</td>
</tr>
<tr>
<td>UNITY_MATRIX_VP</td>
<td>將頂點/方向從世界空間轉換到剪裁空間</td>
</tr>
<tr>
<td>UNITY_MATRIX_T_MV</td>
<td>UNITY_MATRIX_MV的轉置矩陣</td>
</tr>
<tr>
<td>UNITY_MATRIX_IT_MV</td>
<td>UNITY_MATRIX_MV的逆轉置矩陣,可將法線從模型空間傳換到觀察空間</td>
</tr>
<tr>
<td>_Object2World</td>
<td>將頂點/方向從模型空間轉換到世界空間,已修改為unity_ObjectToWord</td>
</tr>
<tr>
<td>_World2Object</td>
<td>將頂點/方向從世界空間轉換到模型空間,已修改為unity_WorldToObject</td>
</tr>
<tr>
<td>_WorldSpaceCameraPos</td>
<td>當前渲染的相機在空間的位置</td>
</tr>
<tr>
<td>_ProjectionParams</td>
<td>x=1(-1),y=near,z=far,w=1+1/far, near和far是近遠裁屏幕到相機的距離</td>
</tr>
<tr>
<td>_ScreenParams</td>
<td>x=width,y=height,z=1+1/width,w=1+1/height</td>
</tr>
<tr>
<td>_ZBufferParams</td>
<td>=x=1-far/near,y=far/near,z=x/far,w=y/far</td>
</tr>
<tr>
<td>unity_OrthoParams</td>
<td>x=正交投影相機的寬度,y=正交投影相機的高度,z未定義,w=1(正交相機)/0(透視相機)</td>
</tr>
<tr>
<td>unity_CameraProjection</td>
<td>該相機的投影矩陣</td>
</tr>
<tr>
<td>unity_CameraInvProjection</td>
<td>該相機的投影矩陣的逆矩陣</td>
</tr>
<tr>
<td>unity_CameraWorldClipPlanes[6]</td>
<td>該相機的6個剪裁螢幕在世界空間下的等式,儲存順序:左右下上近遠</td>
</tr>
<tr>
<td>UNITY_LIGHTMODEL_AMBIENT</td>
<td>向前渲染下的環境光訊息</td>
</tr>
<tr>
<td>_LightColor0</td>
<td>光源顏色</td>
</tr>
<tr>
<td>_WorldSpaceLightPos0</td>
<td>光源方向</td>
</tr>
<tr>
<td>_LightMatrix0</td>
<td>世界空間到光源空間的變換矩陣</td>
</tr>
<tr>
<td>unity_4LightPosX0</td>
<td>僅用於ForwardBase,前4個非重要光源的世界空間下的x座標</td>
</tr>
<tr>
<td>unity_4LightPosY0</td>
<td>僅用於ForwardBase,前4個非重要光源的世界空間下的y座標</td>
</tr>
<tr>
<td>unity_4LightPosZ0</td>
<td>僅用於ForwardBase,前4個非重要光源的世界空間下的z座標</td>
</tr>
<tr>
<td>unity_4LightAtten0</td>
<td>僅用於ForwardBase,前4個非重要光源的衰減因子</td>
</tr>
<tr>
<td>unity_LightColor</td>
<td>數組,僅用於ForwardBase,前4個非重要光源的顏色</td>
</tr>
<tr>
<td>_Time</td>
<td>(t/20, t, 2t, 3t)</td>
</tr>
<tr>
<td>_SinTime</td>
<td>(t/8, t/4, t/2, t)</td>
</tr>
<tr>
<td>_CosTime</td>
<td>(t/8, t/4, t/2, t)</td>
</tr>
<tr>
<td>unity_DeltaTime</td>
<td>(dt, 1/dt, smoothDt, 1/smoothDt</td>
</tr>
<tr>
<td>_CameraDepthTexture</td>
<td>深度紋理,使用SAMPLE_DEPTH_TEXTURE函數獲取深度值,使用Linear0Depth線性化深度值</td>
</tr>
<tr>
<td>_CameraDepthNormalsTexture</td>
<td>深度法線紋理,使用DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, i.uv).xy)獲取[-1,1]之間的法線值</td>
</tr>
<tr>
<td>unity_SpecCube0</td>
<td>天空盒貼圖</td>
</tr>
<tr>
<td>unity_SpecCube0_HDR</td>
<td>用來解碼天空盒顏色:DecodeHDR(UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, i.worldRefl), unity_SpeCube0_HDR)</td>
</tr>
</table>
8.語義
---
<table>
<tr>
<td>語義</td>
<td>說明</td>
</tr>
<tr>
<td>VPOS</td>
<td>
螢幕座標,x=ScreenWidth+0.5,y=ScreenHeight+0.5, <br>
z=[0(near),1(far)],w=1(正交投影)/[1/near,1/far](透視投影)
</td>
</tr>
<tr>
<td>WPOS</td>
<td>
同VPOS <br>
注:使用這兩個語義定義的輸入input可得到視口空間座標:input.xy/_ScreenParams.xy<br>
另一種等價方法:頂點函數中用ComputeScreenPos計算螢幕空間座標,再在片元函數中用結果srcPos.xy/srcPos.w
</td>
</tr>
</table>
9.方法定義
---
<table>
<tr>
<td>方法</td>
<td>說明</td>
</tr>
<tr>
<td>UNITY_UV_STARTS_AT_TOP</td>
<td>判斷當前平台是否DirectX,一半配合_MainTex_TexelSize.y(負數說明開啟了抗鋸齒)進行uv反轉</td>
</tr>
<tr>
<td>USING_DIRECTIONAL_LIGHT</td>
<td>判斷是否使用平行光</td>
</tr>
</table>
<br>
參考:https://blog.csdn.net/qq_34469717/article/details/78427241
---