GPU instancing
Gambar batching panggilan

Menciptakan naungan yang mendukung sikap GPU

Halaman ini berisi informasi tentang cara menambahkan dukungan GPUSicing ke Unity kustom shaderProgram yang berjalan di GPU. More info
Lihat di Glossary
. Ini pertama menjelaskan kata kunci naungan, variabel, dan fungsi naungan Unity kustom perlu mendukung GPU tenggelam. Kemudian termasuk contoh cara menambahkan data per-instance untuk kedua kantung surface shadersCara merampingkan naungan menulis untuk Pipeline Render Built-in. More info
Lihat di Glossary
dan vertex/fragment.

Kompatibilitas pipa Render

Feature Built-in Render PipelineA series of operations that take the contents of a Scene, and displays them on a screen. Unity lets you choose from pre-built render pipelines, or write your own. More info
See in Glossary
Universal Render Pipeline (URP) High Definition Render Pipeline (HDRP) Custom Scriptable Render Pipeline (SRP)
Custom GPU instanced shaders Yes No No No

Modifikasi Shader

Bagian ini berisi informasi tentang penambahan naungan yang berkaitan dengan GPU.

Addition Description
#pragma multi_compile_instancing Hasilkan varian yang tidak tepat. Ini diperlukan untuk fragmen dan vertex shadersProgram yang berjalan pada setiap simpul model 3D ketika model sedang diberikan. More info
Lihat di Glossary
. Ini adalah opsional untuk Permukaan Shaders.
#pragma instancing_options Tentukan pilihan yang digunakan Unity misalnya. Untuk informasi pada sakelar opsi yang tersedia, lihat [#brincar_pilihan] (#Instancing_pilihan).
UNITY_VERTEX_INPUT_INSTANCE_ID Tentukan ID instance di struktur input / output naungan simpul. Untuk menggunakan macro ini, aktifkan kata kunci naungan INSTANCING_ON. Jika tidak, Unity tidak mengatur ID instance. Login Untuk mengakses ID instance, gunakan
di dalam #ifdef INSTANCING_ Login Jika Anda tidak menggunakan blok ini, varian gagal untuk dikompilasi.vertexInput.instanceID inside an #ifdef INSTANCING_ON block. If you don’t use this block, variants fail to compile.
UNITY_INSTANCING_BUFFER_START(bufferName) Tentukan awal penyangga konstan per-instance bernama bufferName. Gunakan makro ini dengan UNITY_INSTANCING_BUFFER_END untuk membungkus deklarasi properti yang ingin Anda unik untuk setiap kasus. Tentukan sifat di dalam penyangga menggunakan UNITY_DEFINE_INSTANCED_PROP.
UNITY_INSTANCING_BUFFER_END(bufferName) Tentukan akhir penyangga konstan per-instance bernama bufferName. Gunakan makro ini dengan UNITY_INSTANCING_BUFFER_START untuk membungkus deklarasi properti yang ingin Anda unik untuk setiap kasus. Tentukan sifat di dalam penyangga menggunakan UNITY_DEFINE_INSTANCED_PROP.
UNITY_DEFINE_INSTANCED_PROP(type, propertyName) Tentukan properti naungan per-instance dengan tipe dan nama yang ditentukan. Dalam contoh di bawah ini, properti _Color unik.
UNITY_SETUP_INSTANCE_ID(v); Memungkinkan fungsi naungan untuk mengakses ID instance. Untuk naungan simpul, makro ini diperlukan pada awal. Untuk warna fragmen, penambahan ini opsional. Sebagai contoh, lihat Vertex dan warna fragmen.
UNITY_TRANSFER_INSTANCE_ID(v, o); Salin ID instance dari struktur input ke struktur output di naungan simpul. Gunakan makro ini jika Anda perlu mengakses data per-instance di naungan fragmen.
UNITY_ACCESS_INSTANCED_PROP(bufferName, propertyName) Mengakses properti naungan per-instance dalam penyangga konstan. Unity menggunakan ID instance untuk indeks ke array data instance. bufferName harus sesuai dengan nama penyangga konstan yang mengandung properti yang ditentukan. Ini makro kompilasi berbeda untuk INSTANCING_ ON dan varian non-instancing.

Ketika Anda menggunakan beberapa properti per-instance, Anda tidak perlu mengisi semua objek MaterialPropertyBlock. Juga, jika satu kasus kekurangan properti, Unity mengambil nilai default dari bahan yang direferensikan. Jika bahan tidak memiliki nilai default untuk properti, Unity menetapkan nilai menjadi 0. Jangan meletakkan sifat non-instanced di MaterialPropertyBlock, karena disables ini. Alih-alih, menciptakan bahan yang berbeda untuk mereka.

Instancing_pilihan switch

[#brincar_pilihan] (#pragma-instancing_pilihan) arahan dapat menggunakan sakelar berikut:

Switch Description
forcemaxcount:batchSize dan maxcount:batchSize Pada sebagian besar platform, Unity secara otomatis menghitung ukuran array data. Ini membagi ukuran penyangga konstan maksimum pada perangkat target dengan ukuran struktur yang mengandung semua sifat per-instance. Umumnya, Anda tidak perlu khawatir tentang ukuran batch. Namun, beberapa platform membutuhkan ukuran array tetap. Untuk menentukan ukuran batch untuk platform tersebut, gunakan opsi maxcount. Platform lain mengabaikan opsi ini. Jika Anda ingin memaksa ukuran batch untuk semua platform, gunakan forcemaxcount. Ini berguna ketika, misalnya, proyek Anda menggunakan DrawMeshInstanced untuk mengeluarkan panggilan dengan 256 spritesObjek grafis 2D. Jika Anda digunakan untuk bekerja di 3D, Sprites pada dasarnya hanya tekstur standar tetapi ada teknik khusus untuk menggabungkan dan mengelola tekstur sprite untuk efisiensi dan kenyamanan selama perkembangan. More info
Lihat di Glossary
. Nilai default untuk dua pilihan adalah 500.
assumeuniformscaling Membangun Unity untuk mengasumsikan bahwa semua kasus memiliki skala seragam (skala yang sama untuk semua X, Y, dan sumbu Z).
nolodfade Membuat Unity tidak menerapkan GPU ke nilai fade LODTeknik Tingkat Detail (LOD) adalah optimasi yang mengurangi jumlah segitiga yang dimiliki Unity untuk membuat GameObject ketika jaraknya dari kamera meningkat. More info
Lihat di Glossary
.
nolightprobe Mencegah Kesatuan dari menerapkan nilai GPU pada nilai Probe Cahayaprobe 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 data oklusi mereka. Menyiapkan opsi ini untuk ON dapat meningkatkan kinerja jika proyek Anda tidak mengandung 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
yang menggunakan baik GPUSicing dan Light Probe.
nolightmap Mencegah Unity dari menerapkan GPU ke nilai informasi dilas 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
. Menyiapkan opsi ini untuk ON dapat meningkatkan kinerja jika proyek Anda tidak mengandung GameObjects yang menggunakan GPUlawcing dan lightmaps.
procedural:FunctionName Hasilkan varian tambahan untuk digunakan dengan Grafik.DrawMeshInstancedIndirect. Pada awal tahap naungan simpul, Unity memanggil fungsi yang ditentukan setelah usus. Untuk mengatur data instance secara manual, tambahkan data per-instance ke fungsi ini dengan cara yang sama Anda biasanya akan menambahkan data per-instance ke naungan. Unity juga memanggil fungsi ini pada awal naungan fragmen jika salah satu sifat instance yang dipetik disertakan dalam naungan fragmen.

Menggunakan varian naungan dengan GPU Suspensioncing

Unity menghasilkan Permukaan naungan dengan tayangan variants secara default, kecuali Anda menentukan noinstancing secara langsung. Unity mengabaikan penggunaan #pragma multi_compile_instancing dalam naungan permukaan.#pragma directive. Unity ignores uses of #pragma multi_compile_instancing in a surface shader.

Unity's Standard and StandardSpecular shaders memiliki dukungan penyedap secara default, tetapi tanpa sifat per-instance selain transformasi.

Jika 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
Anda tidak mengandung GameObjects dengan GPU rincing diaktifkan, maka Unity strips teduh varian. Untuk menimpa perilaku pengupasan:

  1. Pengaturan Proyek Terbuka (menu: Edit > Project Settings).
  2. Go to Graphics.
  3. Pada bagian Shader Stripping, set Instancing Variants ke Keep All.

Menambahkan sifat per-instance ke teduh GPU

Secara default, instance GPU Unity GameObjects dengan Transforms yang berbeda dalam setiap panggilan penarikan yang dicontoh. Untuk menambahkan lebih banyak variasi pada kasus, memodifikasi naungan untuk menambahkan sifat per-sifat sementara seperti warna. Anda dapat melakukan ini baik di naungan permukaan dan di naungan simpul/fragment.

Pedagang kustom tidak perlu data per-instance, tetapi mereka memerlukan ID instance karena manset dunia membutuhkan satu fungsi dengan benar. Naungan permukaan secara otomatis mengatur ID instance, tetapi simpul kustom dan naungan fragmen tidak. Untuk mengatur ID untuk vertex kustom dan warna fragmen, gunakan UNITY_SETUP_INSTANCE_ID pada awal naungan. Contoh cara melakukan ini, lihat Vertex dan warna fragmen.

Ketika Anda menyatakan properti yang dicontoh, Unity mengumpulkan semua nilai properti dari objek MaterialPropertyBlock yang ditetapkan pada GameObjects menjadi panggilan tunggal. Sebagai contoh cara menggunakan benda MaterialPropertyBlock untuk mengatur data per-instance pada runtime, lihat Mengubah data per-instance pada runtime.

Ketika menambahkan data per-instance ke naungan multi-pass, menjaga berikut dalam pikiran:

  • Jika teduh multi-pass memiliki lebih dari dua pass, Unity hanya contoh lulus pertama. Ini karena render Unity kemudian melewati satu objek, yang memaksa perubahan material.
  • Jika Anda menggunakan Forward rendering pathTeknik yang menggunakan pipa render untuk membuat grafik. Memilih jalur rendering yang berbeda mempengaruhi bagaimana pencahayaan dan pembentukan dihitung. Beberapa jalur rendering lebih cocok untuk berbagai platform dan perangkat keras daripada yang lain. More info
    Lihat di Glossary
    di Pipeline Render Built-in, Unity tidak dapat secara efisien objek instance yang dipengaruhi oleh beberapa lampu. Unity hanya dapat menggunakan tempat kejadian secara efektif untuk lulus dasar, tidak untuk melewati tambahan. Untuk informasi lebih lanjut tentang umpan pencahayaan, lihat dokumentasi pada Meneruskan Rendering dan Pass Tags.

Contoh warna permukaan

Contoh berikut menunjukkan cara membuat Shader Permukaan yang dicontoh dengan nilai warna yang berbeda untuk setiap kasus.

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
        // Uses the physically based standard lighting model with shadows enabled for all light types.
        #pragma surface surf Standard fullforwardshadows
        // Use Shader model 3.0 target
        #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"
}

Vertex dan fragmen naungan contoh

Contoh berikut menunjukkan cara membuat simpul dan naungan fragmen yang dicontoh dengan nilai warna yang berbeda untuk setiap kasus. Tidak seperti permukaan naungan, ketika Anda membuat simpul dan fragmen Anda harus menggunakan UNITY_SETUP_INSTANCE_ID untuk mengatur secara manual ID.

Shader "Custom/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 // use this to access instanced properties in the fragment shader.
            };

            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);
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(i);
                return UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
            }
            ENDCG
        }
    }
}

Mengubah data per-instance pada contoh runtime

Contoh berikut menunjukkan cara menggunakan benda MaterialPropertyBlock untuk mengatur data per-instance untuk kelompok GameObjects pada runtime. Ini menetapkan properti _Color dari contoh warna di atas untuk warna acak.

Important: BahanPropertyBlocks memecah SRP Kompatibilitas batcher. Untuk informasi lebih lanjut, lihat Login: Persyaratan dan Kompatibilitas.

using UnityEngine;

public class MaterialPropertyBlockExample : MonoBehaviour
{
    public GameObject[] objects;

    void Start()
    {
        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);
        }
    }
}
GPU instancing
Gambar batching panggilan