gpu instancing unity что это

GPU instancing

Introduction

You can use GPU instancing to draw many identical objects with only a few draw calls. There are some restrictions that you need to bear in mind:

Adding instancing to your objects

A Standard Surface Shader that supports instancing is available in the Unity Editor. Add one to your project by selecting Shader > Standard Surface Shader (Instanced).

Adding the Standard Instanced Shader

Apply this Shader to your GameObject’s Material. In your Material’s Inspector window, click the Shader drop-down, roll over the Instanced field, and choose your instanced Shader from the list:

Assigning the Standard Instanced Shader to a Material

Adding per-instance data

Even though the instanced GameObjects are sharing the same Mesh and Material, you can set Shader properties on a per-object basis using the MaterialPropertyBlock API. In the example below, each GameObject is assigned a random color value using the _Color property:

Adding instancing to your own shaders

The following example takes a simple unlit Shader and makes it capable of instancing:

Added code

Addition Function
#pragma multi_compile_instancing multi_compile_instancing generates a Shader with two variants: one with built-in keyword INSTANCING_ON defined (allowing instancing), the other with nothing defined. This allows the Shader to fall back to a non-instanced version if instancing isn’t supported on the GPU.
UNITY_INSTANCE_ID This is used in the vertex Shader input/output structure to define an instance ID. See SV_InstanceID for more information.
UNITY_INSTANCING_CBUFFER_START(name) / UNITY_INSTANCING_CBUFFER_END Every per-instance property must be defined in a specially named constant buffer. Use this pair of macros to wrap the properties you want to be made unique to each instance.
UNITY_DEFINE_INSTANCED_PROP(float4, color) This defines a per-instance Shader property with a type and a name. In this example, the _color property is unique.
UNITY_SETUP_INSTANCE_ID(v); This makes the instance ID accessible to Shader functions. It must be used at the very beginning of a vertex Shader, and is optional for fragment Shaders.
UNITY_TRANSFER_INSTANCE_ID(v, o); This copies the instance ID from the input structure to the output structure in the vertex Shader. This is only necessary if you need to access per-instance data in the fragment Shader.
UNITY_ACCESS_INSTANCED_PROP(color) This accesses a per-instance Shader property. It uses an instance ID to index into the instance data array.

A note regarding UnityObjectToClipPos

UnityObjectToClipPos(v.vertex) is always preferred where mul(UNITY_MATRIX_MVP,v.vertex) would otherwise be used. While you can continue to use UNITY_MATRIX_MVP as normal in instanced Shaders, UnityObjectToClipPos is the most efficient way of transforming vertex positions from object space into clip space.

UnityObjectToClipPos is optimized to perform two matrix-vector multiplications simultaneously, and is therefore more efficient than performing the multiplication manually, because the Shader compiler does not automatically perform this optimization.

Modifying multi-pass Shaders to work with instancing

For vertex and fragment Shaders, Unity needs to change the way vertex transformations are calculated in multi-pass scenarios (for example, in the ForwardAdd pass) to avoid z-fighting artifacts against the base/first passes due to floating point errors in matrix calculation. To do this, add #pragma force_concat_matrix to the Shader.

Specifically, the vertex transformation in the ForwardAdd pass is calculated by multiplying the M (model) matrix with the VP (view and projection) matrix instead of using a CPU-precomputed MVP matrix.

This is not necessary for surface Shaders, because the correct calculation is automatically substituted.

Batching priority

Static batching takes priority over instancing. If a GameObject is marked for static batching and is successfully batched, instancing is disabled even if its Renderer uses an instancing Shader. When this happens, a warning box appears in the Inspector suggesting that the Static Batching flag be unchecked in the Player Settings.

Instancing takes priority over dynamic batching. If Meshes can be instanced, dynamic batching is disabled.

Further notes

Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at issuetracker.unity3d.com.

Copyright © 2017 Unity Technologies. Publication 5.5-001G 2017-03-29

Источник

GPU instancing

Introduction

GPU Instancing only renders identical Meshes with each draw call, but each instance can have different parameters (for example, color or scale) to add variation and reduce the appearance of repetition.

GPU Instancing can reduce the number of draw calls used per Scene. This significantly improves the rendering performance of your project.

Adding instancing to your Materials

The Enable Instancing checkbox as it appears in the Material Inspector window

With GPU Instancing: A simple Scene that includes multiple identical GameObjects that have GPU Instancing enabled No GPU Instancing: A simple Scene that includes multiple identical GameObjects that do not have GPU Instancing enabled.

When you use GPU instancing, the following restrictions apply:

Unity automatically picks MeshRenderer components and Graphics.DrawMesh calls for instancing. Note that SkinnedMeshRenderer is not supported.

Unity only batches GameObjects that share the same Mesh and the same Material in a single GPU instancing draw call. Use a small number of Meshes and Materials for better instancing efficiency. To create variations, modify your shader scripts A piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary to add per-instance data (see next section to learn more about this).

You can also use the calls Graphics.DrawMeshInstanced and Graphics.DrawMeshInstancedIndirect to perform GPU Instancing from your scripts.

GPU Instancing is available on the following platforms and APIs:

DirectX 11 and DirectX 12 on Windows

OpenGL Core 4.1+/ES3.0+ on Windows, macOS, Linux, and Android

Metal on macOS and iOS

Vulkan on Windows, Linux and Android

PlayStation 4 and Xbox One

WebGL A JavaScript API that renders 2D and 3D graphics in a web browser. The Unity WebGL build option allows Unity to publish content as JavaScript programs which use HTML5 technologies and the WebGL rendering API to run Unity content in a web browser. More info
See in Glossary (requires WebGL 2.0 API)

Adding per-instance data

By default, Unity only batches instances of GameObjects with different Transforms in each instanced draw call. To add more variance to your instanced GameObjects, modify your Shader to add per-instance properties such as Material color.

The example below demonstrates how to create an instanced Shader with different colour values for each instance.

When you declare _Color as an instanced property, Unity will gather _Color values from the MaterialPropertyBlock objects set on GameObjects and put them in a single draw call.

Note that in normal cases (where an instancing shader is not used, or _Color is not a per-instance property), draw call batches are broken due to different values in the MaterialPropertyBlock.

For these changes to take effect, you must enable GPU Instancing. To do this, select your Shader in the Project window, and in the Inspector, tick the Enable Instancing checkbox.

The Enable Instancing checkbox as shown in the Shader Inspector window

Adding instancing to vertex and fragment Shaders

The following example takes a simple unlit Shader and makes it capable of instancing with different colors:

Shader modifications

Notes:

Advanced GPU instancing tips

Batching priority

Graphics.DrawMeshInstanced

Some factors can prevent GameObjects from being instanced together automatically. These factors include Material changes and depth sorting. Use Graphics.DrawMeshInstanced to force Unity to draw these objects using GPU instancing. Like Graphics.DrawMesh, this function draws Meshes for one frame without creating unnecessary GameObjects.

Graphics.DrawMeshInstancedIndirect

Use DrawMeshInstancedIndirect in a script to read the parameters of instancing draw calls, including the number of instances, from a compute buffer. This is useful if you want to populate all of the instance data from the GPU, and the CPU does not know the number of instances to draw (for example, when performing GPU culling). See API documentation on Graphics.DrawMeshInstancedIndirect for a detailed explanation and code examples.

Global Illumination support

Since Unity 2018.1, Global Illumination A group of techniques that model both direct and indirect lighting to provide realistic lighting results. Unity has two global illumination systems that combine direct and indirect lighting: Baked Global Illumination and Enlighten Realtime Global Illumination.
See in Glossary (GI) rendering is supported by GPU Instancing in the form of light probes, occlusion probes (in Shadowmask A Texture that shares the same UV layout and resolution with its corresponding lightmap. More info
See in Glossary mode) and lightmap STs. Standard shaders and surface shaders have GI support automatically enabled.

Dynamic renderers affected by light probes and occlusion probes baked in the scene, and static renderers baked to the same lightmap texture, can be automatically batched together using GPU Instancing by Forward and Deferred render loop.

For Graphics.DrawMeshInstanced, you can enable light probe and occlusion probe rendering by setting the LightProbeUsage argument to CustomProvided and providing a MaterialPropertyBlock with probe data copied in. See API documentation on LightProbes.CalculateInterpolatedLightAndOcclusionProbes for a detailed explanation and code examples.

Global Illumination and GPU Instancing

You can use GPU Instancing to automatically batch dynamic Mesh Renderers A mesh component that takes the geometry from the Mesh Filter and renders it at the position defined by the object’s Transform component. More info
See in Glossary affected by baked Light Probes (including their occlusion data), or static Mesh Renderers baked to the same lightmap Texture, via a Forward and Deferred render loop. See documentation on the Rendering pipeline for more information.

For Graphics.DrawMeshInstanced, you can enable the rendering of Light Probes (including their occlusion data) by setting the LightProbeUsage argument to CustomProvided and providing a MaterialPropertyBlock with probe data copied in. See API documentation on LightProbes.CalculateInterpolatedLightAndOcclusionProbes for a detailed explanation and code examples.

Shader prewarming

You need to prewarm shaders to use instancing on OpenGL if you want absolutely smooth rendering when the shader renders for the first time.

For more information, see Shader loading.

#pragma instancing_options

The #pragma instancing_options directive can use the following switches:

Switch Function
forcemaxcount:batchSize and maxcount:batchSize On most platforms, Unity automatically calculates the instancing data array size by dividing the maximum constant buffer size on the target device with the size of the structure containing all per-instance properties. Generally you don’t need to worry about the batch size. However, on some platforms (Vulkan, Xbox One and Switch), a fixed array size is still required. You can specify the batch size for those platforms by using maxcount option. The option is completely ignored on the other platforms. If you really want to force a batch size for all platforms, use forcemaxcount (for example, when you know you will only issue draws with 256 instanced sprites via DrawMeshInstanced). The default value for the two options is 500.
assumeuniformscaling Use this to instruct Unity to assume that all the instances have uniform scalings (the same scale for all X, Y and Z axes).
nolodfade Use this to prevent Unity from applying GPU Instancing to LOD The Level Of Detail (LOD) technique is an optimization that reduces the number of triangles that Unity has to render for a GameObject when its distance from the Camera increases. More info
See in Glossary fade values.
nolightprobe Use this to prevent Unity from applying GPU Instancing to Light Probe values (including their occlusion data). This is useful for performance if you are absolutely sure that there are no GameObjects using both GPU Instancing and Light Probes.
nolightmap Use this to prevent Unity from applying GPU Instancing to Lightmap ST (atlas information) values. This is useful for performance if you are absolutely sure that there are no GameObjects using both GPU Instancing and lightmaps.
procedural:FunctionName Use this to instruct Unity to generate an additional variant for use with Graphics.DrawMeshInstancedIndirect.
At the beginning of the vertex Shader stage, Unity calls the function specified after the colon. To set up the instance data manually, add per-instance data to this function in the same way you would normally add per-instance data to a Shader. Unity also calls this function at the beginning of a fragment Shader if any of the fetched instance properties are included in the fragment Shader.

UnityObjectToClipPos

The console window (menu: Window > General > Console Abbreviation of game console
See in Glossary ) displays performance warnings if there are still places where UNITY_MATRIX_MVP (along with UNITY_MATRIX_MV ) is used.

Further notes

Surface Shaders have instancing variants generated by default, unless you specify noinstancing in the #pragma surface directive. Standard and StandardSpecular Shaders are already modified to have instancing support, but with no per-instance properties defined other than the transforms. Unity ignores uses of #pragma multi_compile_instancing in a surface Shader.

Unity strips instancing variants if GPU Instancing is not enabled on any GameObject in the Scene. To override the stripping behaviour, open the Graphics settings (menu: Edit > Project Settings, then select the Graphics category), navigate to the Shader stripping section and change the Instancing Variants.

Instanced draw calls appear in the Frame Debugger as Draw Mesh (instanced).

You don’t always need to define per-instance properties. However, setting up an instance ID is mandatory, because world matrices need it to function correctly. Surface shaders automatically set up an instance ID. You must set up the instance ID for Custom Vertex and Fragment shaders manually. To do this, use UNITY_SETUP_INSTANCE_ID at the beginning of the Shader.

When using forward rendering, Unity cannot efficiently instance objects that are affected by multiple lights. Only the base pass can make effective use of instancing, not the added passes. For more information about lighting passes, see documentation on Forward Rendering A rendering path that renders each object in one or more passes, depending on lights that affect the object. Lights themselves are also treated differently by Forward Rendering, depending on their settings and intensity. More info
See in Glossary and Pass Tags

If you have more than two passes for multi-pass Shaders, only the first passes can be instanced. This is because Unity forces the later passes to be rendered together for each object, forcing Material changes.

All the Shader macros used in the above examples are defined in UnityInstancing.cginc. Find this file in the following directory: [Unity installation folder]\Editor\Data\CGIncludes.

2017–10–24 Page amended

Enable instancing checkbox guidance, DrawMeshInstancedIndirect, #pragma multi-compile added in 5.6

Shader warm up for GPU instancing added in 2017.3 NewIn20173

Global Illumination (GI) support in GPU instancing added in 2018.1 NewIn20181

Источник

GPU instancing

Introduction

GPU Instancing only renders identical Meshes with each draw call, but each instance can have different parameters (for example, color or scale) to add variation and reduce the appearance of repetition.

GPU Instancing can reduce the number of draw calls used per Scene. This significantly improves the rendering performance of your project.

Adding instancing to your Materials

The Enable Instancing checkbox as it appears in the Material Inspector window

With GPU Instancing: A simple Scene that includes multiple identical GameObjects that have GPU Instancing enabled No GPU Instancing: A simple Scene that includes multiple identical GameObjects that do not have GPU Instancing enabled.

When you use GPU instancing, the following restrictions apply:

Unity automatically picks MeshRenderer components and Graphics.DrawMesh calls for instancing. Note that SkinnedMeshRenderer is not supported.

Unity only batches GameObjects that share the same Mesh and the same Material in a single GPU instancing draw call. Use a small number of Meshes and Materials for better instancing efficiency. To create variations, modify your shader scripts A piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary to add per-instance data (see next section to learn more about this).

You can also use the calls Graphics.DrawMeshInstanced and Graphics.DrawMeshInstancedIndirect to perform GPU Instancing from your scripts.

GPU Instancing is available on the following platforms and APIs:

DirectX 11 and DirectX 12 on Windows

OpenGL Core 4.1+/ES3.0+ on Windows, macOS, Linux, and Android

Metal on macOS and iOS

Vulkan on Windows, Linux and Android

PlayStation 4 Sony’s eighth generation video game console.
See in Glossary and Xbox One Microsoft’s eighth generation video game console.
See in Glossary

WebGL A JavaScript API that renders 2D and 3D graphics in a web browser. The Unity WebGL build option allows Unity to publish content as JavaScript programs which use HTML5 technologies and the WebGL rendering API to run Unity content in a web browser. More info
See in Glossary (requires WebGL 2.0 API)

Adding per-instance data

By default, Unity only batches instances of GameObjects with different Transforms in each instanced draw call. To add more variance to your instanced GameObjects, modify your Shader to add per-instance properties such as Material color.

The example below demonstrates how to create an instanced Shader with different colour values for each instance.

When you declare _Color as an instanced property, Unity will gather _Color values from the MaterialPropertyBlock objects set on GameObjects and put them in a single draw call.

Note that in normal cases (where an instancing shader is not used, or _Color is not a per-instance property), draw call batches are broken due to different values in the MaterialPropertyBlock.

For these changes to take effect, you must enable GPU Instancing. To do this, select your Shader in the Project window, and in the Inspector, tick the Enable Instancing checkbox.

The Enable Instancing checkbox as shown in the Shader Inspector window

Adding instancing to vertex and fragment Shaders

The following example takes a simple unlit Shader and makes it capable of instancing with different colors:

Shader modifications

Notes:

Advanced GPU instancing tips

Batching priority

Graphics.DrawMeshInstanced

Some factors can prevent GameObjects from being instanced together automatically. These factors include Material changes and depth sorting. Use Graphics.DrawMeshInstanced to force Unity to draw these objects using GPU instancing. Like Graphics.DrawMesh, this function draws Meshes for one frame without creating unnecessary GameObjects.

Graphics.DrawMeshInstancedIndirect

Use DrawMeshInstancedIndirect in a script to read the parameters of instancing draw calls, including the number of instances, from a compute buffer. This is useful if you want to populate all of the instance data from the GPU, and the CPU does not know the number of instances to draw (for example, when performing GPU culling). See API documentation on Graphics.DrawMeshInstancedIndirect for a detailed explanation and code examples.

Global Illumination support

Since Unity 2018.1, Global Illumination A group of techniques that model both direct and indirect lighting to provide realistic lighting results. Unity has two global illumination systems that combine direct and indirect lighting.: Baked Global Illumination, and Realtime Global Illumination (deprecated).
See in Glossary (GI) rendering is supported by GPU Instancing in the form of light probes, occlusion probes (in Shadowmask A Texture that shares the same UV layout and resolution with its corresponding lightmap. More info
See in Glossary mode) and lightmap STs. Standard shaders and surface shaders have GI support automatically enabled.

Dynamic renderers affected by light probes and occlusion probes baked in the scene, and static renderers baked to the same lightmap texture, can be automatically batched together using GPU Instancing by Forward and Deferred render loop.

For Graphics.DrawMeshInstanced, you can enable light probe and occlusion probe rendering by setting the LightProbeUsage argument to CustomProvided and providing a MaterialPropertyBlock with probe data copied in. See API documentation on LightProbes.CalculateInterpolatedLightAndOcclusionProbes for a detailed explanation and code examples.

Global Illumination and GPU Instancing

You can use GPU Instancing to automatically batch dynamic Mesh Renderers A mesh component that takes the geometry from the Mesh Filter and renders it at the position defined by the object’s Transform component. More info
See in Glossary affected by baked Light Probes (including their occlusion data), or static Mesh Renderers baked to the same lightmap Texture, via a Forward and Deferred render loop. See documentation on the Rendering pipeline for more information.

For Graphics.DrawMeshInstanced, you can enable the rendering of Light Probes (including their occlusion data) by setting the LightProbeUsage argument to CustomProvided and providing a MaterialPropertyBlock with probe data copied in. See API documentation on LightProbes.CalculateInterpolatedLightAndOcclusionProbes for a detailed explanation and code examples.

Shader warming-up

Since Unity 2017.3, you need to warm up shaders to use instancing on OpenGL if you want absolutely smooth rendering when the shader renders for the first time. If you warm up shaders for instancing on a platform that doesn’t require shader warm up, nothing will happen.

#pragma instancing_options

The #pragma instancing_options directive can use the following switches:

Switch Function
forcemaxcount:batchSize and maxcount:batchSize On most platforms, Unity automatically calculates the instancing data array size by dividing the maximum constant buffer size on the target device with the size of the structure containing all per-instance properties. Generally you don’t need to worry about the batch size. However, on some platforms (Vulkan, Xbox One and Switch), a fixed array size is still required. You can specify the batch size for those platforms by using maxcount option. The option is completely ignored on the other platforms. If you really want to force a batch size for all platforms, use forcemaxcount (for example, when you know you will only issue draws with 256 instanced sprites via DrawMeshInstanced). The default value for the two options is 500.
assumeuniformscaling Use this to instruct Unity to assume that all the instances have uniform scalings (the same scale for all X, Y and Z axes).
nolodfade Use this to prevent Unity from applying GPU Instancing to LOD The Level Of Detail (LOD) technique is an optimization that reduces the number of triangles that Unity has to render for a GameObject when its distance from the Camera increases. Each LOD level has either a Mesh with a Mesh Renderer component (Mesh LOD level) or a Billboard asset with a Billboard Renderer component (Billboard LOD level). Typically a single GameObject has three or four Mesh LOD levels and one optional Billboard LOD level to represent the same GameObject with decreasing detail in the geometry. More info
See in Glossary fade values.
nolightprobe Use this to prevent Unity from applying GPU Instancing to Light Probe values (including their occlusion data). This is useful for performance if you are absolutely sure that there are no GameObjects using both GPU Instancing and Light Probes.
nolightmap Use this to prevent Unity from applying GPU Instancing to Lightmap ST (atlas information) values. This is useful for performance if you are absolutely sure that there are no GameObjects using both GPU Instancing and lightmaps.
procedural:FunctionName Use this to instruct Unity to generate an additional variant for use with Graphics.DrawMeshInstancedIndirect.
At the beginning of the vertex Shader stage, Unity calls the function specified after the colon. To set up the instance data manually, add per-instance data to this function in the same way you would normally add per-instance data to a Shader. Unity also calls this function at the beginning of a fragment Shader if any of the fetched instance properties are included in the fragment Shader.

UnityObjectToClipPos

The console window (menu: Window > General > Console Abbreviation of game console
See in Glossary ) displays performance warnings if there are still places where UNITY_MATRIX_MVP (along with UNITY_MATRIX_MV ) is used.

Further notes

Surface Shaders have instancing variants generated by default, unless you specify noinstancing in the #pragma surface directive. Standard and StandardSpecular Shaders are already modified to have instancing support, but with no per-instance properties defined other than the transforms. Unity ignores uses of #pragma multi_compile_instancing in a surface Shader.

Unity strips instancing variants if GPU Instancing is not enabled on any GameObject in the Scene. To override the stripping behaviour, open the Graphics settings (menu: Edit > Project Settings, then select the Graphics category), navigate to the Shader stripping section and change the Instancing Variants.

Instanced draw calls appear in the Frame Debugger as Draw Mesh (instanced).

You don’t always need to define per-instance properties. However, setting up an instance ID is mandatory, because world matrices need it to function correctly. Surface shaders automatically set up an instance ID. You must set up the instance ID for Custom Vertex and Fragment shaders manually. To do this, use UNITY_SETUP_INSTANCE_ID at the beginning of the Shader.

When using forward rendering, Unity cannot efficiently instance objects that are affected by multiple lights. Only the base pass can make effective use of instancing, not the added passes. For more information about lighting passes, see documentation on Forward Rendering A rendering path that renders each object in one or more passes, depending on lights that affect the object. Lights themselves are also treated differently by Forward Rendering, depending on their settings and intensity. More info
See in Glossary and Pass Tags

If you have more than two passes for multi-pass Shaders, only the first passes can be instanced. This is because Unity forces the later passes to be rendered together for each object, forcing Material changes.

All the Shader macros used in the above examples are defined in UnityInstancing.cginc. Find this file in the following directory: [Unity installation folder]\Editor\Data\CGIncludes.

2017–10–24 Page amended

Enable instancing checkbox guidance, DrawMeshInstancedIndirect, #pragma multi-compile added in 5.6

Shader warm up for GPU instancing added in 2017.3 NewIn20173

Global Illumination (GI) support in GPU instancing added in 2018.1 NewIn20181

Источник

Читайте также:  при какой температуре скорая забирает в больницу ребенка
Сказочный портал