Unity-GPU 實(shí)例化
簡(jiǎn)介
使用 GPU 實(shí)例化可使用少量繪制調(diào)用一次繪制(或渲染)同一網(wǎng)格的多個(gè)副本。它對(duì)于繪制諸如建筑物、樹(shù)木和草地之類的在場(chǎng)景中重復(fù)出現(xiàn)的對(duì)象非常有用。
GPU 實(shí)例化在每次繪制調(diào)用時(shí)僅渲染相同的網(wǎng)格,但每個(gè)實(shí)例可以具有不同的參數(shù)(例如,顏色或比例)以增加變化并減少外觀上的重復(fù)。
GPU 實(shí)例化可以降低每個(gè)場(chǎng)景使用的繪制調(diào)用數(shù)量。可以顯著提高項(xiàng)目的渲染性能。
為材質(zhì)添加實(shí)例化
要對(duì)材質(zhì)啟用 GPU 實(shí)例化 (GPU Instancing),請(qǐng)?jiān)?Project 窗口中選擇材質(zhì),然后在 Inspector 中勾選?Enable Instancing?復(fù)選框。

僅當(dāng)材質(zhì)著色器支持 GPU 實(shí)例化時(shí),Unity 才會(huì)顯示此復(fù)選框。這包括標(biāo)準(zhǔn) (Standard)、標(biāo)準(zhǔn)鏡面反射 (StandardSpecular) 和所有表面著色器。請(qǐng)參閱有關(guān)標(biāo)準(zhǔn)著色器的文檔以了解更多信息。
下面的截屏顯示了具有多個(gè)游戲?qū)ο蟮南嗤瑘?chǎng)景;在頂部圖像中,啟用了 GPU 實(shí)例化,在底部圖像中沒(méi)有啟用。請(qǐng)注意?FPS、Batches?和?Saved by batching?中的差異。


使用 GPU 實(shí)例化時(shí),存在以下限制:
Unity 自動(dòng)選取要實(shí)例化的網(wǎng)格渲染器組件和?
Graphics.DrawMesh
?調(diào)用。請(qǐng)注意,不支持?SkinnedMeshRenderer。Unity 僅在單個(gè) GPU 實(shí)例化繪制調(diào)用中批量處理那些共享相同網(wǎng)格和相同材質(zhì)的游戲?qū)ο蟆J褂蒙倭烤W(wǎng)格和材質(zhì)可以提高實(shí)例化效率。要?jiǎng)?chuàng)建變體,請(qǐng)修改著色器腳本為每個(gè)實(shí)例添加數(shù)據(jù)(請(qǐng)參閱下一部分了解有關(guān)此內(nèi)容的更多信息)。
您還可以使用?Graphics.DrawMeshInstanced?和?Graphics.DrawMeshInstancedIndirect?調(diào)用來(lái)通過(guò)腳本執(zhí)行 GPU 實(shí)例化。
GPU 實(shí)例化可在以下平臺(tái)和 API 上使用:
Windows 上的?DirectX 11?和?DirectX 12
Windows、macOS、Linux、iOS 和 Android 上的?OpenGL Core 4.1+/ES3.0+
macOS 和 iOS 上的?Metal
Windows、Linux 和 Android 上的?Vulkan
PlayStation 4?和?Xbox One
__WebGL__(需要 WebGL 2.0 API)
添加每個(gè)實(shí)例的數(shù)據(jù)
默認(rèn)情況下,僅當(dāng)游戲?qū)ο笤诿總€(gè)實(shí)例化繪制調(diào)用中具有不同的變換時(shí),Unity 才會(huì)對(duì)這些游戲?qū)ο蟮膶?shí)例進(jìn)行批處理。要為實(shí)例化的游戲?qū)ο筇砑痈嘧凅w,請(qǐng)修改著色器以添加每實(shí)例屬性,例如材質(zhì)顏色。
下面的示例演示了如何為每個(gè)實(shí)例創(chuàng)建具有不同顏色值的實(shí)例化著色器。
Shader "Custom/InstancedColorSurfaceShader" { ? ?
?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 { "RenderType"="Opaque" } ? ? ? ?
? ?LOD 200 ? ? ? ?
? ?CGPROGRAM ? ? ? ?
? ?// 基于物理的標(biāo)準(zhǔn)光照模型,并對(duì)所有光照類型啟用陰影 ? ? ? ?
? ?#pragma surface surf Standard fullforwardshadows ? ? ? ?
? ?// 使用 Shader Model 3.0 目標(biāo) ? ? ? ?
? ?#pragma target 3.0 ? ? ? ?
? ?sampler2D _MainTex; ? ? ? ?
? ?struct Input { ? ? ? ? ? ?
? ? ?float2 uv_MainTex; ? ? ? ?
? ?}; ? ? ? ?
? ?half _Glossiness; ? ? ? ?
? ?half _Metallic; ? ? ? ?
? ?UNITY_INSTANCING_BUFFER_START(Props)
? ?UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
? ?UNITY_INSTANCING_BUFFER_END(Props) ? ? ? ?
? ?void surf (Input IN, inout SurfaceOutputStandard o) { ? ? ? ? ? ?
? ? ?fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * UNITY_ACCESS_INSTANCED_PROP(Props, _Color); ? ? ? ? ? ?
? ? ?o.Albedo = c.rgb; ? ? ? ? ? ?
? ? ?o.Metallic = _Metallic; ? ? ? ? ? ?
? ? ?o.Smoothness = _Glossiness; ? ? ? ? ? ?
? ? ?o.Alpha = c.a; ? ? ? ?
? ?} ? ? ? ?
? ?ENDCG ? ?
?} ? ?
?FallBack "Diffuse"
}
將?_Color
?聲明為實(shí)例化屬性時(shí),Unity 將從游戲?qū)ο笊显O(shè)置的 MaterialPropertyBlock 對(duì)象中收集?_Color
?值,并將它們放在單個(gè)繪制調(diào)用中。
MaterialPropertyBlock props = new MaterialPropertyBlock();
MeshRenderer renderer;
foreach (GameObject obj in objects) { ?
?float r = Random.Range(0.0f, 1.0f); ?
?float g = Random.Range(0.0f, 1.0f); ?
?float b = Random.Range(0.0f, 1.0f); ?
?props.SetColor("_Color", new Color(r, g, b)); ? ?
?renderer = obj.GetComponent<MeshRenderer>(); ?
?renderer.SetPropertyBlock(props);
}
請(qǐng)注意,在通常情況下(不使用實(shí)例化著色器,或者?_Color
?不是每個(gè)實(shí)例的屬性),由于 MaterialPropertyBlock 中的值不同,繪制調(diào)用批次會(huì)被破壞。
要使這些更改生效,必須啟用 GPU 實(shí)例化。為此,請(qǐng)?jiān)?Project 窗口中選擇您的著色器,然后在 Inspector 中勾選?Enable Instancing?復(fù)選框。
向頂點(diǎn)和片元著色器中添加實(shí)例化
下面的示例采用簡(jiǎn)單的無(wú)光照著色器,并使其能夠使用不同的顏色進(jìn)行實(shí)例化:
Shader "SimplestInstancedShader" { ? ?
?Properties ? ?
?{ ? ? ? ?
? ?_Color ("Color", Color) = (1, 1, 1, 1) ? ?
?} ? ?
?SubShader ? ?
?{ ? ? ? ?
? ?Tags { "RenderType"="Opaque" } ? ? ? ?
? ?LOD 100 ? ? ? ?
? ?Pass ? ? ? ?
? ?{ ? ? ? ? ? ?
? ? ?CGPROGRAM ? ? ? ? ? ?
? ? ?#pragma vertex vert ? ? ? ? ? ?
? ? ?#pragma fragment frag ? ? ? ? ? ?
? ? ?#pragma multi_compile_instancing ? ? ? ? ? ?
? ? ?#include "UnityCG.cginc" ? ? ? ? ? ?
? ? ?struct appdata ? ? ? ? ? ?
? ? ?{ ? ? ? ? ? ? ? ?
? ? ? ?float4 vertex : POSITION; ? ? ? ? ? ? ? ?
? ? ? ?UNITY_VERTEX_INPUT_INSTANCE_ID ? ? ? ? ? ?
? ? ?}; ? ? ? ? ? ?
? ? ?struct v2f ? ? ? ? ? ?
? ? ?{ ? ? ? ? ? ? ? ?
? ? ? ?float4 vertex : SV_POSITION;
? ? ? ?UNITY_VERTEX_INPUT_INSTANCE_ID
? ? ? ?// 僅當(dāng)您要訪問(wèn)片元著色器中的實(shí)例化屬性時(shí)才需要。 ? ? ? ? ? ?
? ? ?}; ? ? ? ? ? ?
? ? ?UNITY_INSTANCING_BUFFER_START(Props) ?
? ? ?UNITY_DEFINE_INSTANCED_PROP(float4, _Color) ?
? ? ?UNITY_INSTANCING_BUFFER_END(Props) ? ?
? ? ?v2f vert(appdata v) ? ? ?
? ? ?{ ? ? ? ? ? ? ? ?
? ? ? ?v2f o; ? ? ? ? ? ? ?
? ? ? ?UNITY_SETUP_INSTANCE_ID(v);
? ? ? ?UNITY_TRANSFER_INSTANCE_ID(v, o);
? ? ? ?// 僅當(dāng)您要訪問(wèn)片元著色器中的實(shí)例化屬性時(shí)才需要。 ?
? ? ? ?o.vertex = UnityObjectToClipPos(v.vertex); ?
? ? ? ?return o; ? ? ?
? ? ?} ? ? ? ? ? ? ? ?
? ? ?fixed4 frag(v2f i) : SV_Target ? ?
? ? ?{ ? ? ? ? ? ? ?
? ? ? ?UNITY_SETUP_INSTANCE_ID(i);
? ? ? ?// 僅當(dāng)要在片元著色器中訪問(wèn)任何實(shí)例化屬性時(shí)才需要。
? ? ? ?return UNITY_ACCESS_INSTANCED_PROP(Props, _Color); ?
? ? ?} ? ? ? ? ?
? ? ?ENDCG ? ? ?
? ?} ?
?}
}
著色器修改
添加功能#pragma multi_compile_instancing
用于命令 Unity 生成實(shí)例化變體。對(duì)于表面著色器來(lái)說(shuō)是不需要的。UNITY_VERTEX_INPUT_INSTANCE_ID
用于在頂點(diǎn)著色器輸入/輸出結(jié)構(gòu)中定義實(shí)例 ID。請(qǐng)參閱?SV_InstanceID
?以了解更多信息。UNITY_INSTANCING_BUFFER_START(name)
?/?UNITY_INSTANCING_BUFFER_END(name)
必須在特殊命名的常量緩沖區(qū)中定義每個(gè)實(shí)例的屬性。使用這對(duì)宏來(lái)包裝對(duì)每個(gè)實(shí)例唯一的屬性。UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
用于根據(jù)類型和名稱定義每個(gè)實(shí)例著色器的屬性。在此示例中,_Color
?屬性是唯一的。UNITY_SETUP_INSTANCE_ID(v);
用于使著色器函數(shù)可以訪問(wèn)實(shí)例 ID。它必須在頂點(diǎn)著色器的最開(kāi)頭使用,并且對(duì)于片元著色器是可選的。UNITY_TRANSFER_INSTANCE_ID(v, o);
用于將實(shí)例 ID 從頂點(diǎn)著色器的輸入結(jié)構(gòu)體復(fù)制到輸出結(jié)構(gòu)體中。僅當(dāng)需要訪問(wèn)片元著色器中的每個(gè)實(shí)例的數(shù)據(jù)時(shí)才有必要這樣做。UNITY_ACCESS_INSTANCED_PROP(arrayName, color)
用于訪問(wèn)在實(shí)例化常量緩沖區(qū)中聲明的每個(gè)實(shí)例著色器的屬性。它使用實(shí)例 ID 來(lái)索引到實(shí)例數(shù)據(jù)數(shù)組。該宏中的?arrayName
?必須與?UNITY_INSTANCING_BUFFER_END(name)
?宏中的匹配。
注意:
使用多個(gè)每個(gè)實(shí)例的屬性時(shí),不需要在?
MaterialPropertyBlocks
?中填入所有這些屬性。如果一個(gè)實(shí)例缺少該屬性,Unity 將從引用的材質(zhì)中獲取默認(rèn)值。如果材質(zhì)沒(méi)有該指定屬性的默認(rèn)值,Unity 會(huì)將值設(shè)置為 0。請(qǐng)勿將非實(shí)例化屬性放在?
MaterialPropertyBlock
?中,因?yàn)檫@會(huì)禁用實(shí)例化。請(qǐng)為非實(shí)例化屬性創(chuàng)建不同材質(zhì)。
高級(jí) GPU 實(shí)例化技巧
批處理優(yōu)先級(jí)
進(jìn)行批處理時(shí),Unity 將優(yōu)先處理靜態(tài)批處理,然后再處理實(shí)例化。如果您將其中一個(gè)游戲?qū)ο髽?biāo)記為靜態(tài)批處理,并且 Unity 成功對(duì)其進(jìn)行批處理,則 Unity 會(huì)禁用該游戲?qū)ο蟮膶?shí)例化,即使其渲染器使用實(shí)例化著色器也是如此。發(fā)生這種情況時(shí),Inspector 窗口將顯示一條警告消息,建議您禁用靜態(tài)批處理。要禁用靜態(tài)批處理,請(qǐng)打開(kāi)?Player?設(shè)置(__Edit__ >?Project Settings__,然后選擇?Player__ 類別),打開(kāi)所需平臺(tái)的?Other Settings__,然后在?Rendering__ 部分下面禁用?Static Batching?設(shè)置。
Unity 將優(yōu)先處理實(shí)例化,然后再處理動(dòng)態(tài)批處理。如果 Unity 可以實(shí)例化網(wǎng)格,則會(huì)對(duì)該網(wǎng)格禁用動(dòng)態(tài)批處理。
Graphics.DrawMeshInstanced
某些因素可能會(huì)阻止游戲?qū)ο笸瑫r(shí)自動(dòng)實(shí)例化。這些因素包括材質(zhì)變化和深度排序。使用?Graphics.DrawMeshInstanced?可強(qiáng)制 Unity 使用 GPU 實(shí)例化來(lái)繪制這些對(duì)象。類似于?Graphics.DrawMesh,此函數(shù)為一幀繪制網(wǎng)格,不會(huì)創(chuàng)建不必要的游戲?qū)ο蟆?/p>
Graphics.DrawMeshInstancedIndirect
在腳本中使用?DrawMeshInstancedIndirect
?可從計(jì)算緩沖區(qū)中讀取實(shí)例化繪制調(diào)用的參數(shù),包括實(shí)例數(shù)量。如果要從 GPU 填充所有實(shí)例數(shù)據(jù),并且 CPU 不知道要繪制的實(shí)例數(shù)(例如,執(zhí)行 GPU 剔除時(shí)),這非常有用。請(qǐng)參閱?Graphics.DrawMeshInstancedIndirect?的 API 文檔以了解詳細(xì)說(shuō)明和代碼示例。
全局光照支持
從 Unity 2018.1 開(kāi)始,GPU 實(shí)例化以光照探針、遮擋探針(在?Shadowmask?模式下)和光照貼圖 ST 的形式支持全局光照 (GI) 渲染。標(biāo)準(zhǔn)著色器和表面著色器會(huì)自動(dòng)啟用 GI 支持。
受場(chǎng)景中烘焙的光照探針和遮擋探針影響的動(dòng)態(tài)渲染器,以及烘焙到相同光照貼圖紋理的靜態(tài)渲染器,可以由前向和延遲渲染循環(huán)使用 GPU 實(shí)例化一起自動(dòng)進(jìn)行批處理。
對(duì)于 Graphics.DrawMeshInstanced,通過(guò)將 LightProbeUsage 參數(shù)設(shè)置為 CustomProvided 并提供復(fù)制了探針數(shù)據(jù)的 MaterialPropertyBlock,即可啟用光照探針和遮擋探針?shù)秩?。?qǐng)參閱?LightProbes.CalculateInterpolatedLightAndOcclusionProbes?的 API 文檔以了解詳細(xì)說(shuō)明和代碼示例。
全局光照和 GPU 實(shí)例化
GPU 實(shí)例化支持 Unity 中的全局光照 (GI) 渲染。每個(gè) GPU 實(shí)例可支持來(lái)自不同光照探針、一個(gè)光照貼圖(但該光照貼圖中有多個(gè)圖集區(qū)域)或一個(gè)光照探針代理體組件(為包含所有實(shí)例的空間體積進(jìn)行烘焙)的 GI。標(biāo)準(zhǔn)著色器和表面著色器默認(rèn)啟用該支持。
您可以通過(guò)前向和延遲渲染循環(huán),使用 GPU 實(shí)例化來(lái)自動(dòng)批處理受烘焙光照探針(包括其遮擋數(shù)據(jù))影響的動(dòng)態(tài)網(wǎng)格渲染器,或烘焙到相同光照貼圖紋理的靜態(tài)網(wǎng)格渲染器。請(qǐng)參閱有關(guān)渲染管線的文檔以了解更多信息。
對(duì)于?Graphics.DrawMeshInstanced,通過(guò)將?LightProbeUsage?參數(shù)設(shè)置為?CustomProvided?并提供復(fù)制了探針數(shù)據(jù)的?MaterialPropertyBlock的方式,來(lái)啟用光照探針(包括其遮擋數(shù)據(jù))的渲染。請(qǐng)參閱?LightProbes.CalculateInterpolatedLightAndOcclusionProbes?的 API 文檔以了解詳細(xì)說(shuō)明和代碼示例。
或者,您可以將 LPPV 組件引用和?LightProbeUsage.UseProxyVolume?傳遞到?Graphics.DrawMeshInstanced
。執(zhí)行此操作時(shí),所有實(shí)例都會(huì)對(duì)光照探針數(shù)據(jù)的 L0 和 L1 帶寬進(jìn)行采樣。如果您希望補(bǔ)充 L2 數(shù)據(jù)和遮擋數(shù)據(jù),請(qǐng)使用?MaterialPropertyBlock
。有關(guān)更多信息,請(qǐng)參閱光照探針:技術(shù)信息。
著色器預(yù)熱
從 Unity 2017.3 開(kāi)始,如果您希望在著色器第一次渲染時(shí)獲得絕對(duì)平滑的渲染,則需要預(yù)熱著色器以便在 OpenGL 上使用實(shí)例化。如果您在不需要著色器預(yù)熱的平臺(tái)上為著色器進(jìn)行實(shí)例化預(yù)熱,則不會(huì)發(fā)生任何操作。
請(qǐng)參閱?ShaderVariantCollection.WarmUp?和?Shader.WarmupAllShaders?以了解更多信息。
#pragma instancing_options
#pragma instancing_options
?指令可以使用以下開(kāi)關(guān):
開(kāi)關(guān)功能forcemaxcount:batchSize
?和?maxcount:batchSize
在大多數(shù)平臺(tái)上,Unity 通過(guò)以下方式自動(dòng)計(jì)算實(shí)例化數(shù)據(jù)數(shù)組大?。簩⒛繕?biāo)設(shè)備上的最大常量緩沖區(qū)大小除以包含所有每個(gè)實(shí)例的屬性的結(jié)構(gòu)的大小。通常您不必?fù)?dān)心批次大小。但是,在某些平臺(tái)(Vulkan、Xbox One 和 Switch)上,仍然需要固定的數(shù)組大小。您可以使用?maxcount
?選項(xiàng)來(lái)為這些平臺(tái)指定批次大小。在其他平臺(tái)上,將完全忽略此選項(xiàng)。如果確實(shí)希望強(qiáng)制設(shè)定所有平臺(tái)的批次大小,請(qǐng)使用?forcemaxcount
(例如,當(dāng)您知道自己只會(huì)通過(guò) DrawMeshInstanced 發(fā)出包含 256 個(gè)實(shí)例化精靈的繪制時(shí))。這兩個(gè)選項(xiàng)的默認(rèn)值為 500。assumeuniformscaling
用于命令 Unity 假設(shè)所有實(shí)例都具有統(tǒng)一的縮放(所有 X、Y 和 Z 軸的比例相同)。nolodfade
用于防止 Unity 對(duì)?LOD?淡化值應(yīng)用 GPU 實(shí)例化。nolightprobe
用于防止 Unity 對(duì)光照探針值(包括其遮擋數(shù)據(jù))應(yīng)用 GPU 實(shí)例化。如果您完全確定沒(méi)有任何游戲?qū)ο笳谑褂?GPU 實(shí)例化和光照探針,那么這個(gè)參數(shù)對(duì)提升性能非常有用。nolightmap
用于防止 Unity 對(duì)光照貼圖 ST(圖集信息)值應(yīng)用 GPU 實(shí)例化。如果您完全確定沒(méi)有任何游戲?qū)ο笳谑褂?GPU 實(shí)例化和光照貼圖,那么這個(gè)參數(shù)對(duì)提升性能非常有用。procedural:FunctionName
用于命令 Unity 生成額外變體以用于?Graphics.DrawMeshInstancedIndirect。
在頂點(diǎn)著色器階段開(kāi)始時(shí),Unity 調(diào)用在冒號(hào)后面指定的函數(shù)。要手動(dòng)設(shè)置實(shí)例數(shù)據(jù),請(qǐng)按照通常將每個(gè)實(shí)例數(shù)據(jù)添加到著色器的方式將每個(gè)實(shí)例數(shù)據(jù)添加到此函數(shù)。如果片元著色器中包含任何獲取的實(shí)例屬性,Unity 還會(huì)在片元著色器的開(kāi)頭調(diào)用此函數(shù)。
UnityObjectToClipPos
編寫著色器腳本時(shí),請(qǐng)務(wù)必使用?UnityObjectToClipPos(v.vertex)
?而非?mul(UNITY_MATRIX_MVP,v.vertex)
。
雖然您可以繼續(xù)在實(shí)例化的著色器中正常使用?UNITY_MATRIX_MVP
,但?UnityObjectToClipPos
?是將頂點(diǎn)位置從對(duì)象空間轉(zhuǎn)換為裁剪空間的最有效方法。Unity 還實(shí)現(xiàn)了一個(gè)著色器升級(jí)程序,此程序可掃描項(xiàng)目中的所有著色器,并自動(dòng)用?UnityObjectToClipPos(v)
?替換任何出現(xiàn)的?mul(UNITY_MATRIX_MVP, v)
。
如果仍有某些地方在使用?UNITY_MATRIX_MVP
(以及?UNITY_MATRIX_MV
),控制臺(tái)窗口(菜單:__Window__ >?General?> __Console__)會(huì)顯示性能警告。
其他注意事項(xiàng)
表面著色器具有默認(rèn)情況下生成的實(shí)例化變體,除非您在?
#pragma
?表面指令中指定?noinstancing
。標(biāo)準(zhǔn)著色器和標(biāo)準(zhǔn)鏡面反射著色器已經(jīng)過(guò)修改以支持實(shí)例化,但除了變換之外并沒(méi)有定義每個(gè)實(shí)例的屬性。Unity 將在表面著色器中忽略?#pragma multi_compile_instancing
?的使用。如果未在場(chǎng)景中的任何游戲?qū)ο笊蠁⒂?GPU 實(shí)例化,Unity 會(huì)剝離實(shí)例化變體。要覆蓋此剝離行為,請(qǐng)打開(kāi)?Graphics?設(shè)置(菜單:__Edit?>?Project Settings__,然后選擇?Graphics?類別),找到?Shader stripping?部分,并更改?Instancing Variants。
對(duì)于?
Graphics.DrawMeshInstanced
,您需要在腳本傳遞到此方法的材質(zhì)上啟用 GPU 實(shí)例化。但是,Graphics.DrawMeshInstancedIndirect
?不會(huì)要求您啟用 GPU 實(shí)例化。間接實(shí)例化關(guān)鍵字?PROCEDURAL_INSTANCING_ON
?不受剝離的影響。實(shí)例化的繪制調(diào)用在幀調(diào)試器 (Frame Debugger)?中顯示為?Draw Mesh (instanced)。
并非總是需要定義每個(gè)實(shí)例的屬性。但是,必須設(shè)置實(shí)例 ID,因?yàn)槭澜缇仃囆枰拍苷_\(yùn)行。表面著色器會(huì)自動(dòng)設(shè)置實(shí)例 ID。您必須手動(dòng)設(shè)置自定義頂點(diǎn)和片元著色器的實(shí)例 ID。為此,請(qǐng)?jiān)谥鏖_(kāi)頭使用?
UNITY_SETUP_INSTANCE_ID
。使用前向渲染時(shí),Unity 無(wú)法有效地實(shí)例化受多個(gè)光源影響的對(duì)象。只有基礎(chǔ) pass 能有效使用實(shí)例化,但添加的 pass 不行。有關(guān)光照 pass 的更多信息,請(qǐng)參閱有關(guān)前向渲染和?Pass 標(biāo)簽的文檔
如果多 pass 著色器有兩個(gè)以上的 pass,則只有第一個(gè) pass 可以實(shí)例化。這是因?yàn)?Unity 強(qiáng)制將后續(xù) pass 針對(duì)每個(gè)對(duì)象一起渲染,從而強(qiáng)制更改材質(zhì)。
以上示例中使用的所有著色器宏都在?UnityInstancing.cginc?中定義。請(qǐng)?jiān)谝韵履夸浿胁檎掖宋募篬Unity 安裝文件夾]\Editor\Data\CGIncludes。