1.Shader在什么情況下使用
Particles/Additive(粒子/疊加)到了粒子系列了,之所以先寫前面幾篇是因為本shader中都用到了记劈,篇幅有限勺鸦,因此分了幾篇來寫。本文注釋中有關(guān)INSTANCE_ID和軟粒子的深度計算方法都沒有搞明白目木,不懂的部分只能后面再深入研究了不能阻擋學習的腳步换途。
2.Shader的價值(用的多不多),Shader的難度
Additive應(yīng)該是用的非常多的,難度非常大军拟,畢竟有些細節(jié)我還沒搞明白剃执。
3.代碼詳細注釋
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Legacy Shaders/Particles/Additive" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)//明調(diào)顏色
_MainTex ("Particle Texture", 2D) = "white" {}//貼圖
_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0//軟粒子因子
}
Category {
Tags {
"Queue"="Transparent" //申明渲染隊列為透明(3000)
"IgnoreProjector"="True"http://忽略所有陰影
"RenderType"="Transparent" //聲明為透明物體
"PreviewType"="Plane" //指示材質(zhì)檢視面板預(yù)覽應(yīng)如何顯示材質(zhì)。默認情況下懈息,材質(zhì)顯示為球體肾档,但也可以將 PreviewType 設(shè)置為“Plane”(將顯示為 2D)或“Skybox”(將顯示為天空盒)
}
// Blend SrcAlpha One//透明混合模式
// ColorMask指定渲染結(jié)果的輸出通道,而不是通常的 RGBA 四個通道都被寫入
// ColorMask RGB辫继,RBA等怒见,意思是輸出顏色中RGB,RBA通道會被寫入
// ColorMask R姑宽,意思是輸出顏色中只有R通道會被寫入
// ColorMask 0遣耍,意思是不會輸出任何顏色
// 默認值為RGBA,即四個通道都寫入
ColorMask RGB
// //雙面顯示低千,關(guān)閉裁剪
// Cull Off
// //關(guān)閉燈光影響
// Lighting Off
// //關(guān)閉深度寫入
// ZWrite Off
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
//使用您定義的一組關(guān)鍵字來編譯多個實例配阵。查看已編譯的著色器,multi_compile_particles添加了SOFTPARTICLES_ON和SOFTPARTICLES_OFF示血,因此棋傍,這只是Unity自己的粒子關(guān)鍵字風格,包含該關(guān)鍵字难审。此外瘫拣,您可以在質(zhì)量設(shè)置中切換關(guān)鍵字。
//簡單說所有multi_compile開頭的都是聲明宏定義
//之后就可以用#if xxxx #endif了
//或者使用官方定義的宏定義如下告喊,可以自動生成一些宏定義
// #pragma multi_compile_particles表示允許使用官方的軟陰影粒子SOFTPARTICLES_ON/SOFTPARTICLES_OFF的宏定義開關(guān)
#pragma multi_compile_particles
//霧效宏定義麸拄,不了解可以看霧效篇
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 _TintColor;
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
//在“頂點著色器輸入/輸出”結(jié)構(gòu)中定義一個語義為SV_InstanceID的元素。一些要更改的屬性黔姜,則可以根據(jù)ID進行更改拢切,而無需為MaterialPropertyBlock設(shè)置其他屬性。
//在UnityInstancing.cginc文件中可找到UNITY_VERTEX_INPUT_INSTANCE_ID的定義
//#define UNITY_VERTEX_INPUT_INSTANCE_ID uint instanceID : SV_InstanceID;
//通常用在GPU Instancing和VR中
//在VR中他們將實例ID和眼睛索引傳遞給片段著色器秆吵。這使您可以訪問片段著色器中的實例化屬性淮椰,以及進行可能需要的每眼唯一工作。例如纳寂,如果您使用任何視圖矩陣或投影矩陣或片段著色器中的相機位置主穗,則這些都需要眼圖索引以提供正確的值,否則毙芜,您將始終訪問左眼忽媒。
//這部分網(wǎng)上資料太少-。-搜不到腋粥,暫時不理解晦雨,就先這樣吧
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
////霧效架曹,不了解可以看霧效篇
UNITY_FOG_COORDS(1)
//如果啟用軟粒子
#ifdef SOFTPARTICLES_ON
float4 projPos : TEXCOORD2;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
//同UNITY_VERTEX_INPUT_INSTANCE_ID
//需要寫在vert shader的最前面
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
//取裁剪空間頂點位置
o.vertex = UnityObjectToClipPos(v.vertex);
//如果軟粒子系統(tǒng)打開,需要#pragma multi_compile_particles
//開關(guān)在質(zhì)量設(shè)置里
#ifdef SOFTPARTICLES_ON
//ComputeScreenPos傳入裁剪空間頂點坐標變換到齊次坐標系下的坐標
//齊次坐標就是將笛卡爾坐標轉(zhuǎn)成矩陣闹瞧,便于變換操作
o.projPos = ComputeScreenPos (o.vertex);
//計算頂點攝像機空間的深度:距離裁剪平面的距離音瓷,線性變化;
//在頂點著色器中取出深度信息儲存到projPos夹抗,在片段著色器中使用
COMPUTE_EYEDEPTH(o.projPos.z);
#endif
//獲取mesh頂點色
//一般情況下頂點色都是沒有使用的默認為白色
o.color = v.color;
//將模型頂點的uv和Tiling、Offset兩個變量進行運算纵竖,計算出實際顯示用的頂點uv
//如果不需要Tiling漠烧、Offset可以移除
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
//霧效,不了解可以看霧效篇
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
float _InvFade;
fixed4 frag (v2f i) : SV_Target
{
#ifdef SOFTPARTICLES_ON
//獲得當前片元顯示的深度
//LinearEyeDepth 負責把深度紋理的采樣結(jié)果轉(zhuǎn)換到視角空間下的深度值
float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
//頂點計算出來的深度
float partZ = i.projPos.z;
//saturate將值限制到0-1
//使用混合度_InvFade乘以兩個深度的差
//有關(guān)這兩個深度查到的信息不多靡砌,暫時也搞不明白已脓,先擱這后面明白了再更
float fade = saturate (_InvFade * (sceneZ-partZ));
//混合度影響一下透明度
i.color.a *= fade;
#endif
//最終顏色混合
// alpha should not have double-brightness applied to it, but we can't fix that legacy behavior without breaking everyone's effects, so instead clamp the output to get sensible HDR behavior (case 967476)alpha不應(yīng)該應(yīng)用雙倍的亮度,但是我們不能在不破壞每個人的效果的情況下修復遺留行為通殃,所以取而代之的是鉗制輸出以獲得合理的HDR行為(案例967476)
fixed4 col = 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
//限制透明度區(qū)間
col.a = saturate(col.a);
//霧效混合度液,不了解可以看霧效篇
UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); // fog towards black due to our blend mode由于我們的混合模式霧向黑色
return col;
}
ENDCG
}
}
}
}
4.Shader編寫思路,用到的知識點
粒子其實主要就是顯示原本的顏色并且提亮画舌,本Shader涵蓋了很多如適配性代碼堕担,其中軟粒子主要是指粒子圖像邊緣混合時柔化,具體可以自行百度曲聂,其他的知識點參考本系列前面幾篇霹购。
Legacy Shaders下的Particles系列基本與本文98%相似,各個不同僅修改了混合方式朋腋,至于透明混合方式寫法都比較簡單齐疙,本文不再討論,讀者自行研究(本系列的主要目的是梳理官方shader了解各種語法用法知識點旭咽,而非實現(xiàn)具體邏輯及shader效果)贞奋。