Untuk membuat jumlah instance besar efisien, BRG menggunakan mode shaderProgram yang berjalan di GPU. More info
Lihat di Glossary baru yang disebut DOTS Instancing. Setiap warna yang digunakan BRG harus mendukung DOTS Instancing. Dalam naungan tradisional, naungan melewati array untuk setiap properti yang dicontoh dalam penyangga yang konstan atau seragam, seperti setiap elemen di setiap array mengandung nilai properti untuk instance tunggal dalam penarikan. Dalam teduh DOTS Instanced, Unity melewati satu integer 32-bit ke naungan untuk setiap properti DOTS Instanced. Integer 32-bit ini disebut nilai metadata. Integer ini dapat mewakili apa pun yang Anda inginkan, tetapi biasanya itu mewakili offset di penyangga dari mana data properti beban naungan misalnya bahwa naungan rendering.
Login Instancing memiliki banyak keuntungan dibandingkan dengan peninggalan tradisional, termasuk berikut:
Untuk mendukung DOTS Ketidakseimbangan, naungan perlu melakukan berikut:
#pragma target 4.5
atau lebih tinggi.DOTS_INSTANCING_ON
. Tentukan ini dengan #pragma multi_compile _ DOTS_INSTANCING_ON
.Note: Shader Graphs dan naungan yang Unity menyediakan dukungan URP dan HDRP DOTS Instancing.
Untuk memuat data instance, seperti merubah matriks, naungan perlu mendefinisikan sifat-sifat yang diinduksi DOTS. Di bawah ini adalah contoh blok properti DOTS Instanced sederhana:
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float4, Color)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
Untuk menandai awal dan akhir blok properti, gunakan makro UNITY_DOTS_INSTANCING_START
dan UNITY_DOTS_INSTANCING_END
diikuti oleh nama blok. Contohnya menggunakan nama MaterialPropertyMetadata
. Ada tiga nama blok yang diperbolehkan:
Naungan dapat mendeklarasikan salah satu dari masing-masing, sehingga teduh DOTS Instanced dapat memiliki antara nol dan tiga blok tersebut. Kode naungan yang ditentukan Unity tidak menggunakan UserPropertyMetadata sehingga nama ini dijamin gratis untuk Anda gunakan. URP dan HDRP mendefinisikan BuiltinPropertyMetadata untuk setiap warna yang mereka berikan dan mendefinisikan MaterialPropertyMetadata untuk sebagian besar dari mereka juga, sehingga praktik terbaik untuk menggunakan UserPropertyMetadata. Anda warna kustom dapat menggunakan semua tiga nama mungkin, bahkan semua sekaligus.
Blok dapat berisi sejumlah definisi properti yang timbul DOTS diformat seperti:
UNITY_DOTS_INSTANCED_PROP(PropertyType, PropertyName)
PropertyType
bisa menjadi tipe HLSL built-in (seperti uint, float4, float4x4, atau int2x4) kecuali vektor bool, dan PropertyName
adalah nama properti DOTS Instanced. Login Properti yang sangat terpisah dari sifat bahan biasa, dan Anda dapat memberi mereka nama yang sama dengan properti material biasa lainnya. Hal ini dimungkinkan karena makro UNITY_DOTS_INSTANCED_PROP
menghasilkan nama konstan khusus yang Unity mengenali bahwa tidak bertentangan dengan nama properti lainnya. Shaders yang Unity memberikan sifat yang timbul dari nama yang sama dengan sifat material biasa, tetapi Anda tidak perlu mengikuti konvensi ini.
Secara internal, Unity menyediakan naungan dengan nilai metadata integer 32-bit untuk setiap properti DOTS Instanced naungan menyatakan. Unity menetapkan nilai metadata ketika kode Anda membuat panggilan BatchRendererGroup.AddBatch untuk membuat batch yang terkait dengan penarikan. Nilai metadata default ke 0
jika Unity tidak mengaturnya. Naungan juga memiliki akses ke ByteAddressBuffer unity_DOTSInstanceData
yang set Unity ke GraphicsBuffer Anda lulus sebagai argumen ke BatchRendererGroup.AddBatch
. Penyangga ini biasanya di mana naungan memuat data instance dari. Beberapa batch dapat berbagi satu GraphicsBuffer, tetapi juga dimungkinkan untuk setiap batch untuk menggunakan GraphicsBuffer terpisah sendiri untuk unity_DOTSInstanceData
.
Note: Unity tidak menyediakan data yang ada distansi DOTS secara otomatis. Ini tanggung jawab Anda untuk memastikan bahwa penyangga unity_DOTSInstanceData
setiap batch berisi data yang benar. Data Instance harus mencakup banyak properti yang Unity biasanya menyediakan untuk GameObjectsObjek mendasar dalam adegan Unity, yang dapat mewakili karakter, props, pemandangan, kamera, waypoints, dan banyak lagi. Fungsi GameObject didefinisikan oleh Komponen yang melekat padanya. More info
Lihat di Glossary, seperti mengubah matriks, koefisien light probeprobe cahaya menyimpan informasi tentang bagaimana cahaya melewati ruang di tempat kejadian Anda. Koleksi probe cahaya yang diatur dalam ruang tertentu dapat meningkatkan pencahayaan pada objek bergerak dan pemandangan LOD statis dalam ruang itu. More info
Lihat di Glossary, dan koordinasi tekstur lightmapTekstur pra-render yang mengandung efek sumber cahaya pada objek statis di tempat kejadian. Lightmaps dilalui atas geometri adegan untuk menciptakan efek pencahayaan. More info
Lihat di Glossary.
Untuk mengakses properti DOTS Instanced, naungan Anda dapat menggunakan salah satu makro akses yang disediakan Unity. makro akses menganggap bahwa data instance di unity_DOTSInstanceData
menggunakan tata letak berikut:
unity_DOTSInstanceData
.0
, setiap contoh menggunakan nilai dari indeks instance nol. Ini berarti setiap beban instance langsung dari alamat byte dalam nilai metadata. Dalam hal ini, penyangga hanya perlu menyimpan nilai tunggal, bukan satu nilai per kasus.1
, alamat harus mengandung array di mana Anda dapat menemukan nilai indeks instance instanceID
menggunakan AddressOfInstance0 + sizeof(PropertyType) * instanceID
. Dalam hal ini, Anda harus memastikan bahwa setiap indeks instance yang diberikan memiliki data yang valid dalam buffer. Jika tidak, akses keluar dan perilaku yang tidak ditentukan dapat terjadi.Anda juga dapat mengatur nilai metadata langsung yang berguna jika Anda ingin menggunakan sumber data kustom yang tidak menggunakan tata letak di atas, seperti tekstur.
Unity menyediakan makro akses berikut:
Access macro | Description |
---|---|
UNITY_ACCESS_DOTS_INSTANCED_PROP(PropertyType, PropertyName) |
Kembalikan nilai yang dimuat dari unity_DOTSInstanceData menggunakan tata letak yang dijelaskan di atas. Shaders yang Unity menyediakan menggunakan versi ini untuk properti bawaan DOTS Instanced yang tidak memiliki nilai default untuk jatuh kembali. |
UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(PropertyType, PropertyName) |
Kembali sama dengan UNITY_ACCESS_DOTS_INSTANCED_PROP , kecuali jika sedikit nilai metadata yang paling signifikan adalah nol, mengembalikan nilai default. Nilai default adalah nilai dari properti bahan biasa dengan nama yang sama dengan properti DOTS Instanced, yang mengapa Shaders yang Unity menyediakan penggunaan konvensi di mana sifat DOTS Instanced memiliki nama yang sama sebagai sifat material biasa. Saat menggunakan nilai default, makro akses tidak mengakses unity_DOTSInstanceData sama sekali. Shaders yang Unity menyediakan menggunakan makro akses ini untuk properti material DOTS Instanced, sehingga beban jatuh kembali ke set nilai pada material. |
UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_CUSTOM_DEFAULT(PropertyType, PropertyName, DefaultValue) |
Kembali sama dengan UNITY_ACCESS_DOTS_INSTANCED_PROP kecuali sedikit nilai metadata yang paling signifikan adalah nol, di mana kasus makroreturns DefaultValue ini bukan, dan tidak mengakses unity_DOTSInstanceData . |
UNITY_DOTS_INSTANCED_METADATA_NAME(PropertyType, PropertyName) |
Kembalikan nilai metadata langsung tanpa mengakses apa pun. Ini berguna untuk skema pemuatan data instance kustom. |
Contoh cara menggunakan makro ini, lihat Akses makro contoh.
Selain makro akses, Unity menyediakan fungsi naungan yang memuat nilai-nilai konstan langsung dari data perintah menggambar. Shaders yang Unity menyediakan penggunaan fungsi ini.
Unity menyediakan fungsi naungan berikut:
Shader function | Description |
---|---|
LoadDOTSInstancedData_RenderingLayer |
Mengembalikan renderingLayerMask untuk perintah menggambar. |
LoadDOTSInstancedData_MotionVectorsParams |
Mengembalikan Mode generasi vektor gerak untuk perintah menggambar. Ini diformat sebagai float4, yang merupakan apa yang diharapkan oleh naungan Unity. |
LoadDOTSInstancedData_WorldTransformParams |
Mengembalikan apakah untuk menggambar instance dengan berliku segitiga berbalik. SitemapFlipWinding. |
LoadDOTSInstancedData_LightData |
Kembali apakah Lampu Directional utama sceneAdegan berisi lingkungan dan menu permainan Anda. Pikirkan setiap file Adegan unik sebagai tingkat yang unik. Di setiap Adegan, Anda menempatkan lingkungan, hambatan, dan dekorasi, pada dasarnya merancang dan membangun permainan Anda dalam potongan-potongan. More info Lihat di Glossary aktif untuk instance. Lampu utama dapat dinonaktifkan untuk beberapa alasan, misalnya jika cahaya sudah termasuk dalam peta cahaya. |
LoadDOTSInstancedData_LODFade |
Mengembalikan nilai silang 8 bit yang Anda set jika Login Bendera CrossFade ditetapkan. Jika bendera tidak diatur, nilai pengembalian tidak ditentukan. |
Bagian ini berisi contoh makro akses yang disediakan Unity dan instruksi untuk cara menggunakan makro ini untuk mengakses data per-instance dan data konstan.
Dalam contoh ini:
Color
adalah 0x80001000
.5
.Karena bit yang paling signifikan sudah diatur, makro aksesor tidak memuat default. Ini berarti bahwa c0
, c1
, dan c2
akan memiliki nilai yang sama, dimuat dari alamat unity_DOTSInstanceData
.0x1050
.
void ExamplePerInstance()
{
// rawMetadataValue will contain 0x80001000
uint rawMetadataValue = UNITY_DOTS_INSTANCED_METADATA_NAME(float4, Color);
float4 c0 = UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, Color);
float4 c1 = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4, Color);
float4 c2 = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_CUSTOM_DEFAULT(float4, Color, float4(1, 2, 3, 4));
}
Dalam contoh ini:
Color
adalah 0x00001000
.5
.Karena bit yang paling signifikan tidak diatur, makro aksesor yang jatuh kembali ke default tidak mengakses unity_DOTSInstanceData
. Ini berarti bahwa:
c0
akan mengandung nilai dari alamat unity_DOTSInstanceData
0x1000
.c1
akan mengandung nilai properti bahan biasa Color, dan menyebabkan kesalahan kompilasi jika properti warna tidak ada.c2
akan mengandung (1, 2, 3, 4)
karena itu dilewatkan sebagai nilai default eksplisit.void ExampleConstant()
{
// rawMetadataValue will contain 0x00001000
uint rawMetadataValue = UNITY_DOTS_INSTANCED_METADATA_NAME(float4, Color);
float4 c0 = UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, Color);
float4 c1 = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4, Color);
float4 c2 = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_CUSTOM_DEFAULT(float4, Color, float4(1, 2, 3, 4));
}
Ini adalah praktik terbaik untuk menginisialisasi 64 byte pertama dari semua penyangga unity_DOTSInstanceData
untuk nol dan meninggalkan mereka tidak digunakan. Ini karena nilai metadata default yang digunakan Unity untuk semua nilai metadata tidak ditentukan selama pembuatan batch adalah nol. Secara khusus, ketika naungan memuat nilai metadata nol dari UNITY_ACCESS_DOTS_INSTANCED_PROP
macro, naungan memuat nilai ini dari alamat zero
karena indeks instance akan disinggung. Memastikan bahwa 64 byte pertama, yang merupakan ukuran tipe nilai terbesar ( matriks float4x4), tidak ada jaminan bahwa beban tersebut diprediksi kembali hasil nol. Jika tidak, naungan bisa memuat sesuatu yang tidak dapat diprediksi, tergantung pada apa yang terjadi di alamat nol.
Ketika menggunakan DOTS Instancing, Shader Graphs dan Shaders yang Unity menyediakan menggunakan konvensi khusus untuk mengubah matriks. Untuk menyimpan memori dan bandwidth GPU, mereka menyimpan matriks ini hanya menggunakan 12 pelampung bukan 16, penuh karena empat pelampung selalu konstan. Naungan ini mengharapkan mengapung diformat dengan cara seperti x, y, dan z setiap kolom dalam matriks disimpan dalam urutan. Dengan kata lain, tiga float pertama adalah x, y, dan z kolom pertama, tiga float berikutnya adalah x, y, dan z dari kolom kedua, dan sebagainya. Matrice tidak menyimpan elemen w
dari setiap kolom. Matrice transformasi pengaruh ini adalah:
unity_ObjectToWorld
unity_WorldToObject
unity_MatrixPreviousM
unity_MatrixPreviousMI
Sampel kode berikut termasuk struct yang mengubah empat-by-empat matriks biasa menjadi 12 konvensi mengapung.
struct PackedMatrix
{
public float c0x;
public float c0y;
public float c0z;
public float c1x;
public float c1y;
public float c1z;
public float c2x;
public float c2y;
public float c2z;
public float c3x;
public float c3y;
public float c3z;
public PackedMatrix(Matrix4x4 m)
{
c0x = m.m00;
c0y = m.m10;
c0z = m.m20;
c1x = m.m01;
c1y = m.m11;
c1z = m.m21;
c2x = m.m02;
c2y = m.m12;
c2z = m.m22;
c3x = m.m03;
c3y = m.m13;
c3z = m.m23;
}
}