Difference between revisions of "GPU Instancer:Features"

From GurBu Wiki
Jump to: navigation, search
(Nested Prefabs support (Unity 2018.3 and later))
(Ability to Extend with Custom Compute Shaders)
(23 intermediate revisions by the same user not shown)
Line 77: Line 77:
  
  
[[File:GPUI HDRP test.gif|thumb|left|450px|HDRP and LWRP SRP Support]]
+
[[File:GPUI HDRP test.gif|frame|left|HDRP and LWRP SRP Support]]
  
  
Line 185: Line 185:
  
  
[[File:GPUIInstanceRemover600.gif|450px|thumb|left|The Instance Remover]]
+
[[File:GPUIInstanceRemover600.gif|frame|left|The Instance Remover]]
  
  
Line 201: Line 201:
  
  
[[File:GPUI-CustomComputeShaderSupport.gif|450px|thumb|left|Boids behavior with a Custom Compute Shader]]
+
[[File:GPUI-CustomComputeShaderSupport.gif|frame|left|Boids Behavior with a Custom Compute Shader]]
  
  
Line 281: Line 281:
  
  
GPU Instancer allows you to work with a no-GameObject workflow to maximize your scene performance. By using this workflow, you can render prefab instances without instantiating GameObjects and therefore not using any CPU time for them. Please not that this is an advanced feature and requires a good understanding of [https://en.wikipedia.org/wiki/Transformation_matrix Transformation Matrices] and [[GPU_Instancer:Terminology#GPU_Instancing|GPU Instancing]].
+
[[File:GPUInstancer-Scr-NoGameObjects.png|450px|thumb|left|The no-GameObject Workflow]]
  
  
The basic idea behind this workflow is supplying an array of Matrix4x4s to the GPU Instancer API to initialize the instances. The below script is an example that demonstrates this:
+
GPU Instancer allows you to work with a no-GameObject workflow to maximize your scene performance. If you don't need any components on your instances (e.g. colliders, rigidbodies, scripts, etc.), you can get to most out of GPU instancing by using this workflow. As such, you can render prefab instances without instantiating GameObjects and therefore not use any CPU time for them. Please not that this is an advanced feature and requires a good understanding of [https://en.wikipedia.org/wiki/Transformation_matrix Transformation Matrices] and [[GPU_Instancer:Terminology#GPU_Instancing|GPU Instancing]].
  
  
{| class="wikitable"
+
The included demo scene '''PrefabsWithoutGameObjects''' is designed to demonstrate an example usage of this workflow, and it is a good starting point. For more information, you can take a look at this [[GPU_Instancer:FAQ#How_Can_I_Use_a_no-GameObject_Workflow.3F|wiki documentation on how you can integrate a no-GameObject workflow]].
|-
 
| <br>
 
 
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">GPUInstancer</span><span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> NoGameObject <span style="color: #008000;">:</span> MonoBehaviour</div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #008000;">{</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// reference to Prefab Manager</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> GPUInstancerPrefabManager prefabManager<span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// reference to prefab</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> GPUInstancerPrefab prefab<span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// size of array and buffers</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> bufferSize<span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// transform data array</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> Matrix4x4<span style="color: #008000;">[</span><span style="color: #008000;">]</span> _matrix4x4Array<span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Use this for initialization</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">void</span> Awake <span style="color: #008000;">(</span><span style="color: #008000;">)</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008000;">{</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// initialize the array with the max size</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; _matrix4x4Array <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Matrix4x4<span style="color: #008000;">[</span>bufferSize<span style="color: #008000;">]</span><span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// set the data of the array</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">(</span><span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> _matrix4x4Array<span style="color: #008000;">.</span><span style="color: #0000FF;">Length</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #008000;">)</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _matrix4x4Array<span style="color: #008000;">[</span>i<span style="color: #008000;">]</span> <span style="color: #008000;">=</span> Matrix4x4<span style="color: #008000;">.</span><span style="color: #0000FF;">TRS</span><span style="color: #008000;">(</span>Random<span style="color: #008000;">.</span><span style="color: #0000FF;">insideUnitSphere</span> <span style="color: #008000;">*</span> <span style="color: #FF0000;">15</span>, Quaternion<span style="color: #008000;">.</span><span style="color: #0000FF;">identity</span>, Vector3<span style="color: #008000;">.</span><span style="color: #0000FF;">one</span><span style="color: #008000;">)</span><span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// initialize the buffers with array</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; GPUInstancerAPI<span style="color: #008000;">.</span><span style="color: #0000FF;">InitializeWithMatrix4x4Array</span><span style="color: #008000;">(</span>prefabManager, prefab<span style="color: #008000;">.</span><span style="color: #0000FF;">prefabPrototype</span>, _matrix4x4Array<span style="color: #008000;">)</span><span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008000;">}</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">void</span> Update<span style="color: #008000;">(</span><span style="color: #008000;">)</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008000;">{</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">(</span>Input<span style="color: #008000;">.</span><span style="color: #0000FF;">anyKeyDown</span><span style="color: #008000;">)</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">{</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// change the data of the array</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">(</span><span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> _matrix4x4Array<span style="color: #008000;">.</span><span style="color: #0000FF;">Length</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #008000;">)</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _matrix4x4Array<span style="color: #008000;">[</span>i<span style="color: #008000;">]</span> <span style="color: #008000;">=</span> Matrix4x4<span style="color: #008000;">.</span><span style="color: #0000FF;">TRS</span><span style="color: #008000;">(</span>Random<span style="color: #008000;">.</span><span style="color: #0000FF;">insideUnitSphere</span> <span style="color: #008000;">*</span> <span style="color: #FF0000;">15</span>, Quaternion<span style="color: #008000;">.</span><span style="color: #0000FF;">identity</span>, Vector3<span style="color: #008000;">.</span><span style="color: #0000FF;">one</span><span style="color: #008000;">)</span><span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// update buffers</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GPUInstancerAPI<span style="color: #008000;">.</span><span style="color: #0000FF;">UpdateVisibilityBufferWithMatrix4x4Array</span><span style="color: #008000;">(</span>prefabManager, prefab<span style="color: #008000;">.</span><span style="color: #0000FF;">prefabPrototype</span>, _matrix4x4Array<span style="color: #008000;">)</span><span style="color: #008000;">;</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">}</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #008000;">}</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #008000;">}</span></div>
 
<div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div>
 
</ol>
 
 
 
|}
 
  
 
<div style="clear: both"></div>
 
<div style="clear: both"></div>
 
<br>
 
<br>
  
=== Automatic detection and updating of transform position, rotation and scale changes ===
+
=== Automatic Detection and Updating of Transform Position, Rotation and Scale Changes ===
 
----
 
----
  
  
[[File:GPUI-AutoTransformUpdates.gif|450px|thumb|left|Automatic Detection of Transform Updates]]
+
[[File:GPUI-AutoTransformUpdates.gif|frame|left|Automatic Detection of Transform Updates]]
  
  
Line 352: Line 307:
 
<br>
 
<br>
  
=== Full or area localized Rigidbody and physics support ===
+
=== Full or Area Localized Rigidbody and Physics Support ===
 
----
 
----
  
  
[[File:GPUIModificationCollider600.gif|450px|thumb|left]]
+
[[File:GPUIModificationCollider600.gif|frame|left|The Modification Collider]]
  
  
Line 367: Line 322:
 
<br>
 
<br>
  
=== Instance based material variations through API (similar to Material Property Blocks) ===
+
=== Instance Based Material Variations Through API (Similar to Material Property Blocks) ===
 
----
 
----
  
Line 382: Line 337:
 
<br>
 
<br>
  
=== API to manage instanced prefabs at runtime ===
+
=== Extensive API to Manage Instanced Prefabs at Runtime ===
 
----
 
----
  
Line 394: Line 349:
 
<br>
 
<br>
  
=== Includes mobile demo scene with custom controllers ===
+
=== Includes Mobile Demo Scene with Custom Controllers ===
 
----
 
----
  
Line 409: Line 364:
 
== Detail Instancing Features ==
 
== Detail Instancing Features ==
 
<br>
 
<br>
=== Dense grass fields and vegetation with very high frame rates ===
+
=== Dense Grass Fields and Vegetation with Very High Frame Rates ===
 
----
 
----
  
Line 427: Line 382:
 
<br>
 
<br>
  
=== Included vegetation shader with wind, shadows, AO, billboarding and various other properties ===
+
=== Included Vegetation Shader with Wind, Shadows, AO, Billboarding and Various Other Features ===
 
----
 
----
  
  
[[File:GPUI-DetailWalk.gif|450px|thumb|left|Wind, Shadows, AO, and More with the GPUI Foliage Shader]]
+
[[File:GPUI-DetailWalk.gif|450px|frame|left|Wind, Shadows, AO, and More with the GPUI Foliage Shader]]
  
  
Line 442: Line 397:
 
<br>
 
<br>
  
=== Support for custom shaders and materials ===
+
=== Support for Custom Shaders and Materials ===
 
----
 
----
  
Line 451: Line 406:
 
<br>
 
<br>
  
=== Cross quadding support: automatically turns grass textures to crossed quads ===
+
=== Cross Quadding Support: Automatically Turns Grass Textures to Crossed Quads ===
 
----
 
----
  
Line 466: Line 421:
 
<br>
 
<br>
  
=== Ability to paint prefabs with custom materials and LOD Groups on the Unity terrain (with Unity terrain tools) ===
+
=== Ability to Paint Prefab Instances with Custom Materials and LOD Groups on the Unity Terrain (with Unity Terrain Tools) ===
 
----
 
----
  
Line 475: Line 430:
 
<br>
 
<br>
  
=== Editor GPU Instancing simulation ===
+
=== Editor GPU Instancing Simulation ===
 
----
 
----
  
Line 489: Line 444:
 
== Tree Instancing Features ==
 
== Tree Instancing Features ==
 
<br>
 
<br>
=== Dense forests with very high frame rates ===
+
=== Dense Forests with Very High Frame Rates ===
 
----
 
----
  
Line 509: Line 464:
 
== Third Party Integrations ==
 
== Third Party Integrations ==
 
<br>
 
<br>
=== Gaia integration ===
+
=== Gaia Integration ===
 
----
 
----
  
Line 524: Line 479:
 
<br>
 
<br>
  
=== Map Magic integration ===
+
=== Map Magic Integration ===
 
----
 
----
  

Revision as of 12:20, 12 February 2019

About | Features | Getting Started | Terminology | Best Practices | F.A.Q.


Contents


General Features


Tens of Thousands of Objects Rendered Lightning Fast in a Single Draw Call



50k Asteroids in the PrefabInstancingDemo Scene


GPU Instancer is an out of the box solution to display extreme numbers of objects on screen with high performance. With a few mouse clicks, you can instance your prefabs and Unity terrain details and trees. To provide the fastest possible performance, GPU Instancer utilizes Indirect GPU Instancing using Unity's DrawMeshInstancedIndirect method and Compute Shaders. GPU Instancing results in magnitudes of performance improvement over static batching and mesh combining. Also, other available solutions for GPU Instancing (including Unity's material option and the DrawMeshInstanced method) fail short on limited buffer sizes and therefore result in more draw calls and less performance. By using the indirect method GPU Instancer aims to provide the ultimate solution for this, and increases performance considerably while rendering the same mesh multiple times.


You can take a look at the Terminology and Best Practices pages for detailed information on GPU Instancing and its best usages.


Whether your game scenes include asteroids in space, houses in a city or forests with dense grass and trees, GPU Instancer can help you get the most out of GPU Instancing in Unity for a better performance.


GPU Frustum Culling



GPU Based Frustum Culling


GPU Instancer by default does not draw instances that are not visible in the camera. This saves GPU resources and results in increased performance. Furthermore, GPU Instancer does all the camera frustum testing and the required culling operations for this with Compute Shaders in the GPU before rendering the instances. Because of this, the culling operations are both faster and they do not take any time in the CPU allowing for more room to run game scripts.

For more information on Frustum Culling and how GPUI implements it, you can take a look at this page.


GPU Occlusion Culling



GPU Based Occlusion Culling


GPU Instancer comes with a GPU based Occlusion Culling feature that works out of the box without the need to bake occlusion maps or any setup at all. This feature uses an implementation of the Hierarchical Z-Buffer (Hi-Z) Occlusion Culling technique, and thus uses the camera's depth for visibility tests. Since all these tests run in the GPU, the operations to decide which instances are visible leverage the power of the graphics card and therefore minimize the overhang created by these visibility tests.


For more information on Occlusion Culling and how GPU Instancer implements it, you can take a look at this wiki page. For best practices on how to utilize this feature, you can check the best practices wiki page.



Automatically Configured Custom Shader Support



Custom Shader with Post Processing


GPU Instancer supports most custom shaders out of the box. The Auto-configuration feature automatically creates a GPUI compatible version of the original shader. GPUI also tracks changes to all the shaders that are used by its instanced prototypes and re-creates the compatible shader if there are any changes in the original. This all works in the background so that you don't have to do any extra work for shader compatibility.


GPUI also supports the Standard and Standard (Specular) Unity built in shaders by default. If you need to use other built-in Unity shaders, you can download these from the Unity Download Archive and GPUI will auto-configure them to work with itself as well.


If for any reason you need to manually configure a shader to work with GPUI, you can find the information on how to achieve this in this wiki document.


Support for HDRP and LWRP Render Pipelines



HDRP and LWRP SRP Support


GPU Instancer supports the new High Definition and Lightweight Render Pipelines. GPUI auto-configures the shaders used by these SRP workflows just like any other custom shader.


Complex Hierarchies of Prefabs Instanced with a Single Click



GPU Instancer does not impose any limitations on how the prefab should be like in order to instance it. You can have as many levels of children in the prefab's hierarchy as you would like. This helps especially when using GPUI in your existing scenes since the scene elements are not required to be specially designed for use with GPUI.


For information on what kinds of prefabs will benefit most from GPU Instancing, you can take a look at the Best Practices wiki page.


Multiple Sub-meshes Support



Unity uses one material for each submesh that a mesh has. GPU Instancer fully supports this by instancing prefabs that have multiple submeshes in multiple draw calls. A tree prefab that has a single mesh but two materials, (e.g. one for bark and one for leaves) would amount to two draw calls made by GPU Instancer. Since GPUI uses the indirect GPU instancing method, this will amount to two draw calls even if there are 50 thousand trees.


In short, GPUI does not impose a limit on how the meshes should be like and works with multiple submeshes automatically.


LOD Groups and Cross-Fading Support (with Animation or Fade Transition Width)



LOD Groups and LOD Shadows


GPU Instancer features full support for LOD Groups. If a prefab has an LOD Group on it, GPUI will auto detect this and instance each LOD level seperately. All the LOD distance calculations are made in the GPU for the best possible instancing performance. You can choose between dither cross-fading or animated LOD transitions.


Shadows are also fully supported for LOD Groups. Furthermore, GPUI allows you to choose which LOD level the shadows should be drawn from for each instance LOD. Using this feature, you can optimize the performance of your instances even further by using shadows from lower level LODs for mid LOD levels, or turning shadows off completely for lower LOD levels.


Automatic 2D Billboard Generation System



GPUInstancer-Scr-BillboardGenerator.png


GPU Instancer comes with a billboard generator system. A GPUI billboard is a simple quad that shows snapshots of the object from different angles depending on the camera viewing angle. GPUI's billboard generator is mainly designed for use with trees so it generates snapshots of view angles around the world y axis. This means that the billboards do not have view perspectives from up or down.


Bilboards are a great way to increase performance while having vast viewing distances. GPUI adds the generated billboard automatically as the final LOD level (even if the prefab does not have an LOD Group on it). You can also use a custom mesh and material for the billboard if you do not wish to use the billboard that GPUI generates.


Shadow Casting and Receiving Support for Instances (Culled Instances Still Can Cast Shadows)



Shadow Casting


GPU Instancer features full support for shadow casting and receiving for its instances. Shadows are drawn from a separate buffer and because of this GPUI gives flexible control over how shadows are handled. As such, shadows are drawn inside the defined shadow distance and they are not frustum culled. This also prevents any "shadow popping" issues that may be caused by instances that are culled because they are out of the camera frustum.


Optionally, GPUI allows for frustum culling on shadows as well. This is an ideal option for scenarios where shadow popping would not be an issue (e.g. top down cameras, etc.).


GPUI also gives you the option to use a custom shadow distance per prototype - allowing you to fine-tune your scenes for a better performance. The default distance for shadows when creating a prototype is the same with the shadow distance that is defined in the Unity quality settings in your project.


Unity 5.6 Support



Unity 5.6 Support


GPU Instancer provides full support for all versions of Unity from Unity 5.6 and above.


Well Documented API for Procedural Scenes and Runtime Modifications (Example Scenes Included)



Extensive API with Detailed Documentation


GPU Instancer provides an extensive API for runtime scripting. For more information on the API methods and their definition, you can check the API Documentation page. Also, the included demo scenes are designed to exemplify the API usage for most of the API features.


Ability to Remove Instances Inside Bounds or Colliders at Runtime



The Instance Remover


GPU Instancer comes with a component that allows you to easily remove instances from your scenes at runtime without any code. You can attach this component to any GameObject with a Collider on it. When instantiated at runtime, this GameObject will then remove any instances that fall inside its Collider (or optionally Bounds). For detailed information on how to use this component, you can check the Getting Started page.


This feature is also integrated into the GPU Instancer API to allow you to achieve the same effect during runtime inside your scripts. You can also use the API to persist the state of removed instances, etc.



Ability to Extend with Custom Compute Shaders



Boids Behavior with a Custom Compute Shader


GPU Instancer allows you to extend its workflow with custom Compute Shaders. You can use this feature to tap into the GPUI rendering pipeline to modify and translate instances as you wish. An example scene which modifies the instances with boids behavior is included for you to examine.


Please note that this is an advanced feature and requires a good understanding of Compute Shaders to use.


Example Scenes That Showcase GPU Instancer Capabilities



Demo Scenes Included


GPU Instancer comes with various demo scenes. You can find scenes that show the basic detail, tree and prefab instancing along with complex usages such as instance based material variations, custom compute shaders, runtime modification of prototypes, the no-GameObject workflow, etc. All demo scenes are designed to exemplify the uses of GPUI in as much detail as possible.



Prefab Instancing Features


Ability to Automatically Instance Prefabs at Your Scene That You Distribute with your Favorite Prefab Painting Tool



Adding a Prefab Manager

GPU Instancer is designed mainly prioritizing ease of use and non-intrusiveness in mind. A key point in achieving this is the ability to work on existing scenes and without having to design the scene by some special tools to make use of GPUI.


GPUI makes this possible by allowing you to define your prefabs as prototypes in its managers by simply dragging and dropping them on its Prefab Manager. When you first add a prefab as such, GPUI will detect the instances of this prefab in the scene and do all the necessary work (such as creating compatible shaders, registering LOD Groups, etc.) in the background automatically. If you add or remove prefab instances in the scene after this, all you need to do is to click the Register Instances in Scene button to register the changes in the manager.


Thus, to make use of the prefab manager, you can either manually distribute your prefab instances in the scene, or 'paint' them using your favorite prefab painting tool. GPUI will then use the positions, rotations and scales of these instances during runtime once the instances are registered.


For detailed information on the Prefab Manager and its settings, you can check the Getting Started section.


Automatically Add and Remove Instances at Runtime (without any Aditional Code)



Adding and Removing Instances at Runtime


GPU Instancer allows you to add and remove instances during runtime. This can be done automatically without writing any additional code, in which case GPUI will keep track of new instantiations (or destroying) of the prefab instances and will handle the prototype GPU buffers accordingly.


For more control, you can also use the GPU Instancer API to handle this yourself - or completely register and initialize the managers with exactly the instances you want.


The included demo scene AddRemoveInstancesDemo is intended to demonstrate an example usage of the API for adding/removing instances. For more information on this, you can see the wiki documentation on adding and removing prototype instances at runtime.


Nested Prefabs Support (Unity 2018.3 and Later)



Nested Prefabs in Unity 2018.3 and Later


Since version 2018.3, Unity supports nested prefabs. GPU Instancer also provides support for this in the corresponding Unity versions. Thus in Unity versions 2018.3 and later, when you add prefabs within prefabs, GPUI will add those as separate prototypes - allowing you to use a single draw call for all the inner prefab meshes that are shared in other host prefabs.


The no-GameObject Workflow



The no-GameObject Workflow


GPU Instancer allows you to work with a no-GameObject workflow to maximize your scene performance. If you don't need any components on your instances (e.g. colliders, rigidbodies, scripts, etc.), you can get to most out of GPU instancing by using this workflow. As such, you can render prefab instances without instantiating GameObjects and therefore not use any CPU time for them. Please not that this is an advanced feature and requires a good understanding of Transformation Matrices and GPU Instancing.


The included demo scene PrefabsWithoutGameObjects is designed to demonstrate an example usage of this workflow, and it is a good starting point. For more information, you can take a look at this wiki documentation on how you can integrate a no-GameObject workflow.


Automatic Detection and Updating of Transform Position, Rotation and Scale Changes



Automatic Detection of Transform Updates


GPU Instancer optionally keeps track of any transform changes like moving, rotating or scaling of its instances at runtime and applies this to the GPU matrices - allowing you to have dynamic instances without writing any additional code. You can check the wiki documentation of the Runtime Settings to see how you can easily enable this behavior.


Also, the GPU Instancer API features methods to manipulate instance transforms if you wish to achieve this manually.


Full or Area Localized Rigidbody and Physics Support



The Modification Collider


GPU Instancer features various methods that can allow you to use Rigidbody physics with your instances. You can have GPUI leave the Rigidbody components intact on the instance GameObjects, and it will keep track of any transform changes that are applied from physics - and update the instances accordingly. This will allow for the easiest usage of Rigidbodies and you can see how to easily enable this option in the wiki documentation on Runtime Settings.


However, keeping active Rigidbodies on instance GameObjects is not ideal for a huge number of instances. For better control and performance, GPUI comes with a component to address this problem. This component can be attached to any GameObject with a trigger Collider on it, and GPUI will turn instancing off and activate Rigidbodies for the instances that fall inside this collider at runtime. When the instances are out of this collider and their physics movement comes to a halt (the Sleep state), GPUI turns their instancing back on automatically. This helps a lot with using Rigidbodies with optimized performance. You can read more on this component from the wiki documentation on the GPUI Modification Collider.


Instance Based Material Variations Through API (Similar to Material Property Blocks)



Material Variations on Instances of a Single Prototype


GPU Instancing works by drawing a single mesh and material combination multiple times on the screen. This is why GPUI creates its prototypes from Prefab definitions where it uses the mesh and material information for each renderer the Prefab has and issues drawcalls for them seperately. Thus, out of the box, there would not be any variations for the materials of the prefab instances. However, GPUI offers a solution for having material variations through the GPU Instancer API. The included demo scene ColorVariationsDemo is intended as an example usage of this, so you can take a look at it to get started. Please note, however, that this is an advanced feature and will require you to do some scripting and shader editing.


For detailed information on how to use this feature, you can take a look at this wiki documentation.


Extensive API to Manage Instanced Prefabs at Runtime



Extensive API with Detailed Documentation


You can use the GPU Instancer API to manage your instanced Prefabs at runtime smoothly through scripting. All the API methods are designed to be straightforward and to allow you to tap into the GPUI rendering pipeline. Using this API, you can enable/disable instancing per instance basis, add and remove instances, update transform matrices, use material variations, have a no-GameObject workflow and much more. For a detailed list of all the API methods, you can take a look at the GPU Instancer API documentation.


Includes Mobile Demo Scene with Custom Controllers



Prefab Instancing Demo Scene Mobile Version


GPU Instancer features full mobile support for devices that use OpenGL ES 3.1, Vulkan or Metal (iOS). The core code includes customization where necessary to target a wide range of (high-end) mobile platforms. The download package also includes a mobile version of the Prefab Instancing scene (PrefabInstancingDemoMobile) with spaceship controls that are designed for mobile. If your project is targeting android mobile platforms, you can take a look at the necessary build setting from this wiki page. For iOS platforms, you should use Metal API and no special build settings are necessary. Please also take a look at the minimum requirements if you wish to target mobile platforms using GPUI.



Detail Instancing Features


Dense Grass Fields and Vegetation with Very High Frame Rates



Dense Grass Fields and Vegetation


One of the best usages of GPU Instancing is to use it for grass and vegetation. The reason for this is, usually foliage meshes tend to be very small in tri-counts, but they are needed in huge numbers in the scene. This is why GPU Instancer has a dedicated Detail Manager that can be used to instance your foliage. The Detail Manager is designed to be fully integrated to the Unity Terrain system, and also very simple to use. It uses the detail prototypes and their data from the Unity Terrain and instances them using the GPUI core rendering system. Applying the indirect instancing technique in combination with GPU culling operations, GPUI can be used to get the most out of GPU Instancing when rendering your foliage - allowing you to have dense vegetation with very high frame rates.


Furthermore, you can use the GPU Instancer API to implement instance changes (such as seasonal coloring, terrain modifications, grass removal, etc.) for your instanced foliage. A demo scene (AddModifyTerrainsRuntimeDemo) is included to demonstrate how to utilize the Detail Manager at runtime.


For best practices when using the Detail Manager, you can take a look at this wiki documentation page.


Included Vegetation Shader with Wind, Shadows, AO, Billboarding and Various Other Features



Wind, Shadows, AO, and More with the GPUI Foliage Shader


GPU Instancer comes with a custom foliage shader. This surface shader has many features such as wind, ambient occlusion and billboarding, etc. that are designed for appealing visuals and solid performance. GPUI uses this foliage shader by default for texture type detail prototypes, and you can also choose to use it for your vegetation prefabs.


For more information on the settings that you can use with this shader, you can take a look at this wiki documentation.


Support for Custom Shaders and Materials



The GPU Instancer Foliage shader would out of the box satisfy the vegetation needs of most projects; but if for any reason you would like to use another custom shader for your texture type vegetation details, you can do so by simply assigning the material you wish to use for them. For example if your project uses HDRP or LWRP, you can use a custom SRP shader to have GPUI render the terrain grass with it. Furthermore, since GPUI will auto-configure most shaders to work with itself, you do not need to take any extra steps to make your shader work with the Detail Manager.


Cross Quadding Support: Automatically Turns Grass Textures to Crossed Quads



Automatic Cross Quads from Detail Textures


GPU Instancer Detail Managers have a feature that turns the single quad texture details from the Unity Terrain to cross quad meshes. The result of this is more geometry to render but denser looking grass and foliage. The Detail Manager offers various options to choose from about this feature: you can have cross quads that are made of 2 quads, 3 quads or 4 quads - or you can have a single quad that can optionally be billboarded. These options serve as quality options and the lower amount of quads will result in better performance, where the higher amount will result in denser details.


If you prefer to use cross quads, GPUI gives you the option to furthermore add a single quad version as a lower LOD level to your detail prototype. This is because cross quads might not make much difference in farther distances in comparison to billboards - so this option increases performance while still keeping cross quadded quality.


Ability to Paint Prefab Instances with Custom Materials and LOD Groups on the Unity Terrain (with Unity Terrain Tools)



The Detail Manager accepts two type of prototypes. You can either define a texture or a prefab as a detail prototype. These correspond to the Grass Texture and Detail Mesh type detail prototypes in the Unity Terrain respectively; and when added to a scene with an existing terrain, GPUI creates the corresponding prototypes as such. However, unlike what you can do with the Unity Terrain, you can add prefabs with custom materials and LOD Groups on them to the Detail Manager. In both cases, GPUI will add the prefab as a detail mesh to the Unity Terrain. In the case of prefabs with custom materials, GPUI will use the material on the prefab during runtime to render the prototype. If there is an LOD Group in the prefab, GPUI will add the first LOD level as a detail mesh to the terrain, but will render the prefab with all LOD levels during runtime. This helps remove some of the Unity Terrain limitations while still being able to use its terrain data and painting tools.


Editor GPU Instancing Simulation



Instancing Simulation in the Editor


GPU Instancer features a simulation mode that you can use to quickly check how the instanced version of the Unity Terrain will look like with the current Detail Manager settings. Please note that this feature is not intended to take over rendering in the editor; rather, it is designed to visualize the terrain with the shaders and settings that you have in the Detail Manager without having to enter the play mode.


Tree Instancing Features


Dense Forests with Very High Frame Rates



Dense Forests with Very High Frame Rates


GPU Instancer provides full support for Unity Terrain Trees. SpeedTree, Tree Creator and Soft Occlusion trees (as well as most custom tree shaders) are supported out of the box and with full wind animation support.


Just like the Detail Manager, the Tree Manager also uses data from the Unity Terrain, allowing you to distribute your trees with the Unity terrain tools or use GPU Instancer in your existing scenes. If you want to use trees without registering them to the Unity terrain (or if you wish to distribute your trees as prefab instances), you can use the Prefab Manager to render your trees instead.


GPUI also features an automatic billboard generator and renderer system that will render the trees at far distances as single quads - increasing your scene performance further while GPU instancing the billboards as well. GPUI also gives you full control over the billboards that will be used; you can optionally decide not to use the generated billboards and use custom billboards/impostors instead of them. This is done simply by providing a mesh and a material to use for the tree instance billboards.


Third Party Integrations


Gaia Integration



Gaia Integration


GPU Instancer has a built-in integration with Gaia. If you wish to use Gaia generated terrains with GPUI, you can use the GX tab under the Gaia Manager to add all desired GPUI managers to your scene.


For more information on using Gaia with GPU Instancer, you can check this wiki documentation.


Map Magic Integration



MapMagic World Generator Integration


GPU Instancer has a built-in integration with MapMagic World Generator. Through a dedicated integration manager, GPUI keeps track of the infinite terrains generated by MapMagic and instances the prefabs, details and trees you have on them.


For more information on how to use MapMagic with GPU Instancer, you can take a look at this wiki documentation.