Unity-粒子系統(tǒng)頂點(diǎn)流和標(biāo)準(zhǔn)著色器支持
如果習(xí)慣編寫(xiě)自己的著色器,請(qǐng)使用添加到渲染器模塊的方式配置粒子系統(tǒng),從而將更多數(shù)據(jù)傳入自定義著色器。
有許多內(nèi)置數(shù)據(jù)流可供選擇,例如速度、大小和中心位置。除了能夠創(chuàng)建強(qiáng)大的自定義著色器之外,這些流還可以帶來(lái)大量其他好處:
使用?Tangent?流來(lái)支持法線(xiàn)貼圖粒子。?可以刪除 Color,然后添加 Tangent?UV2?和?AnimBlend?流以便在粒子上使用標(biāo)準(zhǔn)著色器。 * 需要輕松執(zhí)行翻頁(yè)動(dòng)畫(huà)的線(xiàn)性紋理混合,請(qǐng)?zhí)砑?UV2 和 AnimBlend 流,并附加粒子/動(dòng)畫(huà) Alpha 混合著色器 (Particles/Anim Alpha Blended Shader)(請(qǐng)參閱下面的示例截屏,了解如何對(duì)其進(jìn)行設(shè)置)。
此外還有兩個(gè)完全自定義的每粒子數(shù)據(jù)流(ParticleSystemVertexStreams.Custom1?和?ParticleSystemVertexStreams.Custom2),可通過(guò)腳本填充。請(qǐng)使用數(shù)據(jù)數(shù)組調(diào)用?SetCustomParticleData?和?GetCustomParticleData?以便使用它們。有兩種方式使用它們:
通過(guò)將您自己的數(shù)據(jù)附加到粒子來(lái)驅(qū)動(dòng)腳本中的自定義行為;例如,將“生命”值附加到每個(gè)粒子。
通過(guò)添加兩個(gè)自定義流中的其中一個(gè)流將此數(shù)據(jù)傳入著色器,就像將任何其他流發(fā)送到著色器一樣(請(qǐng)參閱?ParticleSystemRenderer.EnableVertexStreams)。為了詳細(xì)說(shuō)明第一個(gè)示例,自定義的生命值屬性現(xiàn)在也可以驅(qū)動(dòng)某種視覺(jué)效果,以及驅(qū)動(dòng)基于腳本的游戲邏輯。
添加頂點(diǎn)流時(shí),Unity 會(huì)在每一項(xiàng)旁邊的括號(hào)中提供一些信息,用于在著色器中讀取正確的數(shù)據(jù):

括號(hào)中的每一項(xiàng)對(duì)應(yīng)于一個(gè)頂點(diǎn)著色器輸入,應(yīng)在著色器中指定。以下是此配置的正確輸入結(jié)構(gòu)。
struct appdata_t
{ ? ? ? ?
?float4 vertex : POSITION; ? ?
?float3 normal : NORMAL; ? ?
?fixed4 color : COLOR; ? ?
?float4 texcoords : TEXCOORD0; ?
?float texcoordBlend : TEXCOORD1; ?
};
請(qǐng)注意,UV 和 UV2 均傳遞到 TEXCOORD0 的不同部分中,因此我們對(duì)兩者使用單個(gè)聲明。要訪(fǎng)問(wèn)著色器中的每一個(gè),應(yīng)使用 xy 和 zw 標(biāo)示字母。這樣即可有效地打包頂點(diǎn)數(shù)據(jù)。
以下是一個(gè)翻頁(yè)動(dòng)畫(huà)著色器的示例。它使用默認(rèn)輸入(__Position、Normal、Color、UV__),但還為第二個(gè) UV 流 (UV2) 和翻頁(yè)動(dòng)畫(huà)幀信息 (AnimBlend) 使用了兩個(gè)額外的流。
Shader "Particles/Anim Alpha Blended"
{
?Properties {
? ?_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5) ?
? ?_MainTex ("Particle Texture", 2D) = "white" {}
? ?_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
?}
?Category
?{ ?
? ?Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane"
? ? ? ? } ?
? ?Blend SrcAlpha OneMinusSrcAlpha ?
? ?ColorMask RGB ?
? ?Cull Off Lighting Off ZWrite Off ?
? ?SubShader { ?
? ? ?Pass { ? ? ?
? ? ? ?CGPROGRAM ? ?
? ? ? ?#pragma vertex vert ? ?
? ? ? ?#pragma fragment frag ? ? ?
? ? ? ?#pragma target 2.0 ? ?
? ? ? ?#pragma multi_compile_particles ?
? ? ? ?#pragma multi_compile_fog ? ? ?
? ? ? ?#include "UnityCG.cginc" ?
? ? ? ?sampler2D _MainTex; ? ? ?
? ? ? ?fixed4 _TintColor; ? ?
? ? ? ?struct appdata_t { ? ? ?
? ? ? ? ?float4 vertex : POSITION; ?
? ? ? ? ?fixed4 color : COLOR; ? ?
? ? ? ? ?float4 texcoords : TEXCOORD0; ? ?
? ? ? ? ?float texcoordBlend : TEXCOORD1; ?
? ? ? ? ?UNITY_VERTEX_INPUT_INSTANCE_ID ?
? ? ? ?}; ? ? ? ? ?
? ? ? ?struct v2f { ? ? ?
? ? ? ? ?float4 vertex : SV_POSITION; ? ?
? ? ? ? ?fixed4 color : COLOR; ? ? ?
? ? ? ? ?float2 texcoord : TEXCOORD0; ? ? ?
? ? ? ? ?float2 texcoord2 : TEXCOORD1; ? ?
? ? ? ? ?fixed blend : TEXCOORD2; ? ? ?
? ? ? ? ?UNITY_FOG_COORDS(3) ? ? ? ?
? ? ? ? ?#ifdef SOFTPARTICLES_ON ? ?
? ? ? ? ?float4 projPos : TEXCOORD4; ?
? ? ? ? ?#endif ? ? ? ? ? ?
? ? ? ? ?UNITY_VERTEX_OUTPUT_STEREO ?
? ? ? ?}; ? ? ? ? ?
? ? ? ?float4 _MainTex_ST; ?
? ? ? ?v2f vert (appdata_t v) ?
? ? ? ?{ ? ? ? ? ? ?
? ? ? ? ?v2f o; ? ? ? ?
? ? ? ? ?UNITY_SETUP_INSTANCE_ID(v); ?
? ? ? ? ?UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); ?
? ? ? ? ?o.vertex = UnityObjectToClipPos(v.vertex);
? ? ? ? ?#ifdef SOFTPARTICLES_ON ? ?
? ? ? ? ?o.projPos = ComputeScreenPos (o.vertex); ?
? ? ? ? ?COMPUTE_EYEDEPTH(o.projPos.z); ? ?
? ? ? ? ?#endif ? ? ? ? ? ?
? ? ? ? ?o.color = v.color * _TintColor; ? ?
? ? ? ? ?o.texcoord = TRANSFORM_TEX(v.texcoords.xy,_MainTex);
? ? ? ? ?o.texcoord2 = TRANSFORM_TEX(v.texcoords.zw,_MainTex); ?
? ? ? ? ?o.blend = v.texcoordBlend; ? ? ? ? ?
? ? ? ? ?UNITY_TRANSFER_FOG(o,o.vertex); ? ?
? ? ? ? ?return o; ? ? ? ? ?
? ? ? ?} ? ? ? ? ?
? ? ? ?sampler2D_float _CameraDepthTexture; ? ?
? ? ? ?float _InvFade; ? ? ? ?
? ? ? ?fixed4 frag (v2f i) : SV_Target ? ?
? ? ? ?{ ? ? ?
? ? ? ? ?#ifdef SOFTPARTICLES_ON ? ? ?
? ? ? ? ?float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); ?
? ? ? ? ?float partZ = i.projPos.z; ?
? ? ? ? ?float fade = saturate (_InvFade * (sceneZ-partZ)); ?
? ? ? ? ?i.color.a *= fade; ? ? ?
? ? ? ? ?#endif ? ? ? ? ? ?
? ? ? ? ?fixed4 colA = tex2D(_MainTex, i.texcoord); ?
? ? ? ? ?fixed4 colB = tex2D(_MainTex, i.texcoord2); ? ?
? ? ? ? ?fixed4 col = 2.0f * i.color * lerp(colA, colB, i.blend); ?
? ? ? ? ?UNITY_APPLY_FOG(i.fogCoord, col); ? ? ?
? ? ? ? ?return col; ? ?
? ? ? ?} ? ? ? ? ?
? ? ? ?ENDCG ?
? ? ?} ?
? ?}
?}
}
也可以將表面著色器與此系統(tǒng)一起使用,但還有一些需要注意的事項(xiàng):
表面函數(shù)的輸入結(jié)構(gòu)與頂點(diǎn)著色器的輸入結(jié)構(gòu)不同。需要提供自定義的頂點(diǎn)著色器輸入結(jié)構(gòu)。請(qǐng)參閱下面示例中名為?
appdata_particles
?的結(jié)構(gòu)。構(gòu)建表面著色器時(shí),會(huì)自動(dòng)處理名稱(chēng)以某些標(biāo)記開(kāi)頭的變量。最明顯的就是?
uv
。為防止自動(dòng)處理在此處引起問(wèn)題,請(qǐng)務(wù)必為 UV 輸入指定不同的名稱(chēng)(例如,“texcoord”)。
下面的示例與第一個(gè)示例具有相同的功能,但位于表面著色器中:
Shader "Particles/Anim Alpha Blend Surface" { ?
?Properties { ?
? ?_Color ("Color", Color) = (1,1,1,1) ?
? ?_MainTex ("Albedo (RGB)", 2D) = "white" {} ?
? ?_Glossiness ("Smoothness", Range(0,1)) = 0.5 ?
? ?_Metallic ("Metallic", Range(0,1)) = 0.0 ?
?} ? ?
?SubShader { ? ?
? ?Tags {"Queue"="Transparent" "RenderType"="Transparent"} ?
? ?Blend SrcAlpha OneMinusSrcAlpha ? ? ?
? ?ZWrite off ? ?
? ?LOD 200 ? ? ? ?
? ?CGPROGRAM ? ?
? ?// 這是基于物理的標(biāo)準(zhǔn)光照模型,并對(duì)所有光照類(lèi)型啟用陰影 ?
? ?#pragma surface surf Standard alpha vertex:vert ?
? ?// 使用 Shader Model 3.0 目標(biāo)以獲得更美觀(guān)的光照 ? ?
? ?#pragma target 3.0 ? ?
? ?sampler2D _MainTex; ? ?
? ?struct appdata_particles { ?
? ? ?float4 vertex : POSITION; ?
? ? ?float3 normal : NORMAL; ? ?
? ? ?float4 color : COLOR; ? ? ?
? ? ?float4 texcoords : TEXCOORD0; ? ?
? ? ?float texcoordBlend : TEXCOORD1; ? ?
? ?}; ? ? ?
? ?struct Input { ? ?
? ? ?float2 uv_MainTex; ?
? ? ?float2 texcoord1; ?
? ? ?float blend; ? ?
? ? ?float4 color; ? ?
? ?}; ? ?
? ?void vert(inout appdata_particles v, out Input o)
? ?{
? ? ?UNITY_INITIALIZE_OUTPUT(Input,o); ? ? ?
? ? ?o.uv_MainTex = v.texcoords.xy; ? ? ?
? ? ?o.texcoord1 = v.texcoords.zw; ? ?
? ? ?o.blend = v.texcoordBlend; ?
? ? ?o.color = v.color; ? ?
? ?} ? ?
? ?half _Glossiness; ? ?
? ?half _Metallic; ? ?
? ?fixed4 _Color; ? ?
? ?void surf (Input IN, inout SurfaceOutputStandard o)
? ?{ ? ? ? ?
? ? ?fixed4 colA = tex2D(_MainTex, IN.uv_MainTex); ?
? ? ?fixed4 colB = tex2D(_MainTex, IN.texcoord1); ?
? ? ?fixed4 c = 2.0f * IN.color * lerp(colA, colB, IN.blend) * _Color;
? ? ?o.Albedo = c.rgb; ?
? ? ?// Metallic 和 Smoothness 來(lái)自滑動(dòng)條變量
? ? ?o.Metallic = _Metallic; ?
? ? ?o.Smoothness = _Glossiness; ? ?
? ? ?o.Alpha = c.a; ? ? ?
? ?} ? ?
? ?ENDCG ?
?} ? ?
?FallBack "Diffuse"
}