├── .gitignore
├── Demos-DrawMeshInstancedIndirect
├── Assets
│ ├── FlyCamera.cs
│ ├── FlyCamera.cs.meta
│ ├── InstancedIndirectAppend.meta
│ ├── InstancedIndirectAppend
│ │ ├── InstancedIndirectComputeAppend.cs
│ │ ├── InstancedIndirectComputeAppend.cs.meta
│ │ ├── InstancedIndirectComputeAppend.mat
│ │ ├── InstancedIndirectComputeAppend.mat.meta
│ │ ├── InstancedIndirectComputeAppend.shader
│ │ ├── InstancedIndirectComputeAppend.shader.meta
│ │ ├── InstancedIndirectComputeAppend.unity
│ │ ├── InstancedIndirectComputeAppend.unity.meta
│ │ ├── InstancedIndirectComputeAppendKernel.compute
│ │ └── InstancedIndirectComputeAppendKernel.compute.meta
│ ├── InstancedIndirectCompute.meta
│ ├── InstancedIndirectCompute
│ │ ├── ComputeKernel.compute
│ │ ├── ComputeKernel.compute.meta
│ │ ├── InstancedIndirectComputeExample.cs
│ │ ├── InstancedIndirectComputeExample.cs.meta
│ │ ├── InstancedIndirectComputeExample.unity
│ │ ├── InstancedIndirectComputeExample.unity.meta
│ │ ├── InstancedIndirectComputeSurfaceShader.shader
│ │ ├── InstancedIndirectComputeSurfaceShader.shader.meta
│ │ ├── InstancedIndirectComputeTest.mat
│ │ └── InstancedIndirectComputeTest.mat.meta
│ ├── InstancedIndirectExample.meta
│ ├── InstancedIndirectExample
│ │ ├── Floor.mat
│ │ ├── Floor.mat.meta
│ │ ├── InstancedIndirectExample.cs
│ │ ├── InstancedIndirectExample.cs.meta
│ │ ├── InstancedIndirectExample.unity
│ │ ├── InstancedIndirectExample.unity.meta
│ │ ├── InstancedIndirectSurfaceShader.shader
│ │ ├── InstancedIndirectSurfaceShader.shader.meta
│ │ ├── InstancedIndirectTest.mat
│ │ └── InstancedIndirectTest.mat.meta
│ ├── InstancedIndirectNoBuffer.meta
│ ├── InstancedIndirectNoBuffer
│ │ ├── InstancedIndirectNoBuffer.cs
│ │ ├── InstancedIndirectNoBuffer.cs.meta
│ │ ├── InstancedIndirectNoBuffer.unity
│ │ ├── InstancedIndirectNoBuffer.unity.meta
│ │ ├── InstancedIndirectNoBufferSurfaceShader.shader
│ │ ├── InstancedIndirectNoBufferSurfaceShader.shader.meta
│ │ ├── InstancedIndirectNoBufferTest.mat
│ │ └── InstancedIndirectNoBufferTest.mat.meta
│ ├── InstancedIndirectShadowsIssue.meta
│ └── InstancedIndirectShadowsIssue
│ │ ├── InstancedIndirectShadowsIssue.cs
│ │ ├── InstancedIndirectShadowsIssue.cs.meta
│ │ ├── InstancedIndirectShadowsIssue.mat
│ │ ├── InstancedIndirectShadowsIssue.mat.meta
│ │ ├── InstancedIndirectShadowsIssue.unity
│ │ ├── InstancedIndirectShadowsIssue.unity.meta
│ │ ├── InstancedIndirectShadowsIssueSurfaceShader.shader
│ │ └── InstancedIndirectShadowsIssueSurfaceShader.shader.meta
└── ProjectSettings
│ ├── AudioManager.asset
│ ├── ClusterInputManager.asset
│ ├── DynamicsManager.asset
│ ├── EditorBuildSettings.asset
│ ├── EditorSettings.asset
│ ├── GraphicsSettings.asset
│ ├── InputManager.asset
│ ├── NavMeshAreas.asset
│ ├── NetworkManager.asset
│ ├── Physics2DSettings.asset
│ ├── ProjectSettings.asset
│ ├── ProjectVersion.txt
│ ├── QualitySettings.asset
│ ├── TagManager.asset
│ ├── TimeManager.asset
│ └── UnityConnectSettings.asset
├── LICENSE
├── README.md
└── Untitled.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # =============== #
2 | # Unity generated #
3 | # =============== #
4 | Temp/
5 | Library/
6 | Build/
7 | prints/
8 | #StreamingAssets/
9 | #StreamingAssets.meta
10 |
11 | # ===================================== #
12 | # Visual Studio / MonoDevelop generated #
13 | # ===================================== #
14 | ExportedObj/
15 | StreamingAssets/
16 | obj/
17 | *.svd
18 | *.userprefs
19 | *.csproj
20 | *.pidb
21 | *.suo
22 | *.sln
23 | *.user
24 | *.unityproj
25 | *.booproj
26 |
27 | # ============ #
28 | # OS generated #
29 | # ============ #
30 | .DS_Store
31 | .DS_Store?
32 | ._*
33 | .Spotlight-V100
34 | .Trashes
35 | ehthumbs.db
36 | Thumbs.db
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/FlyCamera.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using UnityEngine.EventSystems;
4 |
5 | public class FlyCamera : MonoBehaviour
6 | {
7 | public Terrain terrain;
8 | public EventSystem eventSystem;
9 |
10 | /**
11 | * Writen by Windexglow 11-13-10. Use it, edit it, steal it I don't care.
12 | * Converted to C# 27-02-13 - no credit wanted.
13 | * Added resetRotation, RF control, improved initial mouse position, 2015-03-11 - Roi Danton.
14 | * Simple flycam I made, since I couldn't find any others made public.
15 | * Made simple to use (drag and drop, done) for regular keyboard layout
16 | * wasdrf : basic movement
17 | * shift : Makes camera accelerate
18 | * space : Moves camera on X and Z axis only. So camera doesn't gain any height
19 | */
20 |
21 | public float minSpeed = 0.5f;
22 | public float mainSpeed = 10f; // Regular speed.
23 | public float shiftMultiplier = 2f; // Multiplied by how long shift is held. Basically running.
24 | public float maxShift = 100000f; // Maximum speed when holding shift.
25 | public float camSens = .35f; // Camera sensitivity by mouse input.
26 | private Vector3 lastMouse = new Vector3(Screen.width / 2, Screen.height / 2, 0); // Kind of in the middle of the screen, rather than at the top (play).
27 | private float totalRun = 1.0f;
28 |
29 | public bool clickToMove = true;
30 | public bool keepItAboveTerrain = true;
31 | public float unitsAboveTerrain = 4f;
32 |
33 | void Start()
34 | {
35 | // Get terrain reference
36 | terrain = Terrain.activeTerrain;
37 | eventSystem = EventSystem.current;
38 | }
39 |
40 |
41 | void Update()
42 | {
43 | // This should prevent the mouse input from getting through the UI.
44 | //if (eventSystem.IsPointerOverGameObject() && !dragging)
45 | // return;
46 |
47 | mainSpeed += Input.GetAxis("Mouse ScrollWheel") * mainSpeed;
48 | if (mainSpeed < minSpeed)
49 | mainSpeed = minSpeed;
50 |
51 | if (clickToMove)
52 | {
53 | if (!Input.GetMouseButton(0))
54 | {
55 | return;
56 | }
57 |
58 | if (Input.GetMouseButtonDown(0))
59 | {
60 | lastMouse = Input.mousePosition;
61 | return;
62 | }
63 | }
64 |
65 | // Mouse input.
66 | lastMouse = Input.mousePosition - lastMouse;
67 | lastMouse = new Vector3(-lastMouse.y * camSens, lastMouse.x * camSens, 0);
68 | lastMouse = new Vector3(transform.eulerAngles.x + lastMouse.x, transform.eulerAngles.y + lastMouse.y, 0);
69 | transform.eulerAngles = lastMouse;
70 | lastMouse = Input.mousePosition;
71 |
72 |
73 | // Keyboard commands.
74 | Vector3 p = getDirection();
75 | if (Input.GetKey(KeyCode.LeftShift))
76 | {
77 | //totalRun += Time.deltaTime;
78 | totalRun += Time.unscaledDeltaTime;
79 | p = p * totalRun * shiftMultiplier;
80 | p.x = Mathf.Clamp(p.x, -maxShift, maxShift);
81 | p.y = Mathf.Clamp(p.y, -maxShift, maxShift);
82 | p.z = Mathf.Clamp(p.z, -maxShift, maxShift);
83 | }
84 | else
85 | {
86 | totalRun = Mathf.Clamp(totalRun * 0.5f, 1f, 1000f);
87 | p = p * mainSpeed;
88 | }
89 |
90 | //p = p * Time.deltaTime;
91 | p = p * Time.unscaledDeltaTime;
92 | Vector3 newPosition = transform.position;
93 | if (Input.GetKey(KeyCode.V))
94 | { //If player wants to move on X and Z axis only
95 | transform.Translate(p);
96 | newPosition.x = transform.position.x;
97 | newPosition.z = transform.position.z;
98 | transform.position = newPosition;
99 | }
100 | else
101 | {
102 | transform.Translate(p);
103 | }
104 |
105 | if (keepItAboveTerrain)
106 | {
107 | // Keep it above terrain
108 | newPosition = transform.position;
109 | newPosition.y = terrain.SampleHeight(newPosition) + terrain.transform.position.y + unitsAboveTerrain;
110 | if (transform.position.y <= newPosition.y)
111 | transform.position = newPosition;
112 | }
113 |
114 |
115 | }
116 |
117 | private Vector3 getDirection()
118 | {
119 | Vector3 p_Velocity = new Vector3();
120 | if (Input.GetKey(KeyCode.W))
121 | {
122 | p_Velocity += new Vector3(0, 0, 1);
123 | }
124 | if (Input.GetKey(KeyCode.S))
125 | {
126 | p_Velocity += new Vector3(0, 0, -1);
127 | }
128 | if (Input.GetKey(KeyCode.A))
129 | {
130 | p_Velocity += new Vector3(-1, 0, 0);
131 | }
132 | if (Input.GetKey(KeyCode.D))
133 | {
134 | p_Velocity += new Vector3(1, 0, 0);
135 | }
136 | if (Input.GetKey(KeyCode.R))
137 | {
138 | p_Velocity += new Vector3(0, 1, 0);
139 | }
140 | if (Input.GetKey(KeyCode.F))
141 | {
142 | p_Velocity += new Vector3(0, -1, 0);
143 | }
144 | return p_Velocity;
145 | }
146 |
147 | public void resetRotation(Vector3 lookAt)
148 | {
149 | transform.LookAt(lookAt);
150 | }
151 | }
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/FlyCamera.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fe47489b52b15664eb0af627736ac604
3 | timeCreated: 1488639142
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 636c2f9965fab2b4691166dd9f10f782
3 | folderAsset: yes
4 | timeCreated: 1488639118
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEngine.Rendering;
3 |
4 | ///
5 | /// This demo shows the use of Compute Shaders to update the object's positions.
6 | /// The buffer is stored and updated directly in GPU.
7 | /// The append buffer can be used when there is an unknown output buffer size.
8 | ///
9 | public class InstancedIndirectComputeAppend : MonoBehaviour
10 | {
11 | public int instanceCount = 100000;
12 | public Mesh instanceMesh;
13 | public Material instanceMaterial;
14 |
15 | public ShadowCastingMode castShadows = ShadowCastingMode.Off;
16 | public bool receiveShadows = false;
17 |
18 | public ComputeShader positionComputeShader;
19 | private int positionComputeKernelId;
20 |
21 | private ComputeBuffer positionAppendBuffer;
22 | private ComputeBuffer argsBuffer;
23 |
24 | void Start()
25 | {
26 | /// it's 5 args: index count per instance, instance count, start index location, base vertex location, start instance location.
27 | argsBuffer = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments);
28 | CreateBuffers();
29 | }
30 |
31 | void Update()
32 | {
33 | // Update position buffer
34 | UpdateBuffers();
35 |
36 | // Render - same old, only now we'll have argsBuffer with the count set from the append result.
37 | Graphics.DrawMeshInstancedIndirect(instanceMesh, 0, instanceMaterial, instanceMesh.bounds, argsBuffer, 0, null, castShadows, receiveShadows);
38 | }
39 |
40 | void UpdateBuffers()
41 | {
42 | /// reset the append buffer counter,
43 | /// this is important! otherwise we'll keep appending to a buffer indefinitely!
44 | positionAppendBuffer.SetCounterValue(0);
45 |
46 | /// TODO this only works with POT, integral sqrt vals
47 | int bs = instanceCount / 64;
48 | positionComputeShader.Dispatch(positionComputeKernelId, bs, 1, 1);
49 | positionComputeShader.SetBuffer(positionComputeKernelId, "positionBuffer", positionAppendBuffer);
50 | positionComputeShader.SetFloat("_Dim", Mathf.Sqrt(instanceCount));
51 |
52 | /// as we don't know exactly how many positions were output, we use this function
53 | /// to copy the count from positionAppendBuffer to argsBuffer, which will be used for rendering.
54 | /// The offset 4 is because the instance count is placed in args[1] for the DrawMeshInstancedIndirect
55 | /// + info https://docs.unity3d.com/ScriptReference/ComputeBuffer.CopyCount.html
56 | ComputeBuffer.CopyCount(positionAppendBuffer, argsBuffer, 4);
57 | }
58 |
59 | void CreateBuffers()
60 | {
61 | if (instanceCount < 1)
62 | instanceCount = 1;
63 |
64 | instanceCount = Mathf.ClosestPowerOfTwo(instanceCount);
65 |
66 | positionComputeKernelId = positionComputeShader.FindKernel("CSPositionKernel");
67 | instanceMesh.bounds = new Bounds(Vector3.zero, Vector3.one * 10000f);
68 |
69 | if (positionAppendBuffer != null)
70 | positionAppendBuffer.Release();
71 |
72 | /// note the compute buffer append type!
73 | positionAppendBuffer = new ComputeBuffer(instanceCount, 16, ComputeBufferType.Append);
74 | positionAppendBuffer.SetCounterValue(0);
75 | instanceMaterial.SetBuffer("positionBuffer", positionAppendBuffer);
76 |
77 | // indirect args
78 | uint numIndices = (instanceMesh != null) ? (uint)instanceMesh.GetIndexCount(0) : 0;
79 | argsBuffer.SetData(new uint[5] { numIndices, (uint)instanceCount, 0, 0, 0 });
80 | }
81 |
82 | void OnDisable()
83 | {
84 | if (positionAppendBuffer != null)
85 | positionAppendBuffer.Release();
86 | positionAppendBuffer = null;
87 |
88 | if (argsBuffer != null)
89 | argsBuffer.Release();
90 | argsBuffer = null;
91 | }
92 |
93 | void OnGUI()
94 | {
95 | GUI.Label(new Rect(265, 12, 200, 30), "Instance Count: " + instanceCount.ToString("N0"));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 52cf2243e9b0a364294cf131471bfbcf
3 | timeCreated: 1481682952
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.mat
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9b63139e12467e443a7a64ff79a90db2
3 | timeCreated: 1481683451
4 | licenseType: Pro
5 | NativeFormatImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.shader:
--------------------------------------------------------------------------------
1 | Shader "Instanced/InstancedIndirectComputeAppend"
2 | {
3 | Properties{
4 | _MainTex("Albedo (RGB)", 2D) = "white" {}
5 | _Glossiness("Smoothness", Range(0,1)) = 0.5
6 | _Metallic("Metallic", Range(0,1)) = 0.0
7 | }
8 | SubShader{
9 | Tags{ "RenderType" = "Opaque" }
10 | LOD 200
11 |
12 | CGPROGRAM
13 | // Physically based Standard lighting model
14 | #pragma surface surf Standard addshadow
15 | #pragma multi_compile_instancing
16 | #pragma instancing_options procedural:setup
17 |
18 | sampler2D _MainTex;
19 |
20 | struct Input {
21 | float2 uv_MainTex;
22 | };
23 |
24 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
25 | StructuredBuffer positionBuffer;
26 | #endif
27 |
28 | void setup()
29 | {
30 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
31 | /// Positions are calculated in the compute shader.
32 | /// here we just use them.
33 | float4 position = positionBuffer[unity_InstanceID];
34 | float scale = position.w;
35 |
36 | unity_ObjectToWorld._11_21_31_41 = float4(scale, 0, 0, 0);
37 | unity_ObjectToWorld._12_22_32_42 = float4(0, scale, 0, 0);
38 | unity_ObjectToWorld._13_23_33_43 = float4(0, 0, scale, 0);
39 | unity_ObjectToWorld._14_24_34_44 = float4(position.xyz, 1);
40 | unity_WorldToObject = unity_ObjectToWorld;
41 | unity_WorldToObject._14_24_34 *= -1;
42 | unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
43 | #endif
44 | }
45 |
46 | half _Glossiness;
47 | half _Metallic;
48 |
49 | float rand(in float2 uv)
50 | {
51 | float2 noise = (frac(sin(dot(uv, float2(12.9898, 78.233) * 2.0)) * 43758.5453));
52 | return abs(noise.x + noise.y) * 0.5;
53 | }
54 |
55 | void surf(Input IN, inout SurfaceOutputStandard o)
56 | {
57 | float4 col = 1.0f;
58 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
59 | col = float4(unity_ObjectToWorld._11, rand(unity_ObjectToWorld._14_34), 1, 1);
60 | #endif
61 |
62 | fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * col;
63 | o.Albedo = c.rgb;
64 | o.Metallic = _Metallic;
65 | o.Smoothness = _Glossiness;
66 | o.Alpha = c.a;
67 | }
68 | ENDCG
69 | }
70 | FallBack "Diffuse"
71 | }
72 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 191cd539e00de8e42b0fae7aa25149e3
3 | timeCreated: 1481683330
4 | licenseType: Pro
5 | ShaderImporter:
6 | defaultTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.unity
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppend.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7382f704d6d6e61478142b52efe0938f
3 | timeCreated: 1481683507
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppendKernel.compute:
--------------------------------------------------------------------------------
1 | #pragma kernel CSPositionKernel
2 |
3 | #define thread_group_size_x 64
4 | #define thread_group_size_y 1
5 |
6 | AppendStructuredBuffer positionBuffer;
7 |
8 | float _Dim;
9 |
10 | float rand(in float2 uv)
11 | {
12 | float2 noise = (frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453));
13 | return abs(noise.x + noise.y) * 0.5;
14 | }
15 |
16 | [numthreads(thread_group_size_x, thread_group_size_y, 1)]
17 | void CSPositionKernel (uint3 id : SV_DispatchThreadID)
18 | {
19 | // this uv assumes the # of instances is _Dim * _Dim.
20 | // so we calculate the uv inside a grid of _Dim x _Dim elements.
21 | float2 uv = float2( floor(id.x / _Dim) / _Dim, (id.x % (int)_Dim) / _Dim);
22 |
23 | // in this case, _Dim can be replaced by the grid size in the world
24 | float4 pos = float4((uv.x - 0.5) * _Dim * 2, 0, (uv.y - 0.5) * _Dim * 2, rand(uv));
25 |
26 | /// in this example, not all threads will output a position.
27 | /// note: the output order is not deterministic!
28 | if (rand(uv) > 0.5)
29 | positionBuffer.Append(pos);
30 | }
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectAppend/InstancedIndirectComputeAppendKernel.compute.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3febdf7cfed45cd4b9684d48d46ecdb7
3 | timeCreated: 1488637146
4 | licenseType: Free
5 | ComputeShaderImporter:
6 | currentAPIMask: 4
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: eeb63abdc338ebb4aaf4ffed4ee4e471
3 | folderAsset: yes
4 | timeCreated: 1488639118
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/ComputeKernel.compute:
--------------------------------------------------------------------------------
1 | #pragma kernel CSPositionKernel
2 |
3 | #define thread_group_size_x 64
4 | #define thread_group_size_y 1
5 |
6 | RWStructuredBuffer positionBuffer;
7 |
8 | float _Dim;
9 | float _Time;
10 |
11 | float rand(in float2 uv)
12 | {
13 | float2 noise = (frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453));
14 | return abs(noise.x + noise.y) * 0.5;
15 | }
16 |
17 | void rotate2D(inout float2 v, float r)
18 | {
19 | float s, c;
20 | sincos(r, s, c);
21 | v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
22 | }
23 |
24 | [numthreads(thread_group_size_x, thread_group_size_y, 1)]
25 | void CSPositionKernel (uint3 id : SV_DispatchThreadID)
26 | {
27 | // this uv assumes the # of instances is _Dim * _Dim.
28 | // so we calculate the uv inside a grid of _Dim x _Dim elements.
29 | float2 uv = float2( floor(id.x / _Dim) / _Dim, (id.x % (int)_Dim) / _Dim);
30 |
31 | // in this case, _Dim can be replaced by the grid size in the world
32 | float4 pos = float4((uv.x - 0.5) * _Dim, 0, (uv.y - 0.5) * _Dim, rand(uv));
33 |
34 | float rotation = pos.w * pos.w * _Time * 0.5f;
35 | rotate2D(pos.xz, rotation);
36 |
37 | positionBuffer[id.x] = pos;
38 | }
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/ComputeKernel.compute.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 64221cf7b19dbb84c8efa10de9ceb22f
3 | timeCreated: 1488637146
4 | licenseType: Free
5 | ComputeShaderImporter:
6 | currentAPIMask: 4
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeExample.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEngine.Rendering;
3 |
4 | ///
5 | /// This demo shows the use of Compute Shaders to update the object's
6 | /// positions. The buffer is stored and updated directly in GPU.
7 | ///
8 | public class InstancedIndirectComputeExample : MonoBehaviour
9 | {
10 | public int instanceCount = 100000;
11 | public Mesh instanceMesh;
12 | public Material instanceMaterial;
13 |
14 | public ShadowCastingMode castShadows = ShadowCastingMode.Off;
15 | public bool receiveShadows = false;
16 |
17 | public ComputeShader positionComputeShader;
18 | private int positionComputeKernelId;
19 |
20 | private ComputeBuffer positionBuffer;
21 | private ComputeBuffer argsBuffer;
22 | private ComputeBuffer colorBuffer;
23 |
24 | private uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
25 |
26 | void Start()
27 | {
28 | argsBuffer = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments);
29 | CreateBuffers();
30 | }
31 |
32 | void Update()
33 | {
34 | // Update position buffer
35 | UpdateBuffers();
36 |
37 | // Render
38 | Graphics.DrawMeshInstancedIndirect(instanceMesh, 0, instanceMaterial, instanceMesh.bounds, argsBuffer, 0, null, castShadows, receiveShadows);
39 | }
40 |
41 | void UpdateBuffers()
42 | {
43 | positionComputeShader.SetFloat("_Time", Time.time);
44 |
45 | /// TODO this only works with POT, integral sqrt vals
46 | int bs = instanceCount / 64;
47 | positionComputeShader.Dispatch(positionComputeKernelId, bs, 1, 1);
48 | }
49 |
50 | void CreateBuffers()
51 | {
52 | if ( instanceCount < 1 ) instanceCount = 1;
53 |
54 | instanceCount = Mathf.ClosestPowerOfTwo(instanceCount);
55 |
56 | positionComputeKernelId = positionComputeShader.FindKernel("CSPositionKernel");
57 | instanceMesh.bounds = new Bounds(Vector3.zero, Vector3.one * 10000f);
58 |
59 | // Positions & Colors
60 | if (positionBuffer != null) positionBuffer.Release();
61 | if (colorBuffer != null) colorBuffer.Release();
62 |
63 | positionBuffer = new ComputeBuffer(instanceCount, 16);
64 | colorBuffer = new ComputeBuffer(instanceCount, 16);
65 |
66 | Vector4[] colors = new Vector4[instanceCount];
67 | for (int i = 0; i < instanceCount; i++)
68 | colors[i] = Random.ColorHSV();
69 |
70 | colorBuffer.SetData(colors);
71 |
72 | instanceMaterial.SetBuffer("positionBuffer", positionBuffer);
73 | instanceMaterial.SetBuffer("colorBuffer", colorBuffer);
74 |
75 | // indirect args
76 | uint numIndices = (instanceMesh != null) ? (uint)instanceMesh.GetIndexCount(0) : 0;
77 | args[0] = numIndices;
78 | args[1] = (uint)instanceCount;
79 | argsBuffer.SetData(args);
80 |
81 | positionComputeShader.SetBuffer(positionComputeKernelId, "positionBuffer", positionBuffer);
82 | positionComputeShader.SetFloat("_Dim", Mathf.Sqrt(instanceCount));
83 | }
84 |
85 | void OnDisable()
86 | {
87 | if (positionBuffer != null) positionBuffer.Release();
88 | positionBuffer = null;
89 |
90 | if (colorBuffer != null) colorBuffer.Release();
91 | colorBuffer = null;
92 |
93 | if (argsBuffer != null) argsBuffer.Release();
94 | argsBuffer = null;
95 | }
96 |
97 | void OnGUI()
98 | {
99 | GUI.Label(new Rect(265, 12, 200, 30), "Instance Count: " + instanceCount.ToString("N0"));
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeExample.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 51ad6be56c44c0c4ba3af455446d6a86
3 | timeCreated: 1481682952
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeExample.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeExample.unity
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeExample.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1ef00fd5ea063284889beac71679c1d6
3 | timeCreated: 1481683507
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeSurfaceShader.shader:
--------------------------------------------------------------------------------
1 | Shader "Instanced/InstancedIndirectCompute"
2 | {
3 | Properties{
4 | _MainTex("Albedo (RGB)", 2D) = "white" {}
5 | _Glossiness("Smoothness", Range(0,1)) = 0.5
6 | _Metallic("Metallic", Range(0,1)) = 0.0
7 | }
8 | SubShader{
9 | Tags{ "RenderType" = "Opaque" }
10 | LOD 200
11 |
12 | CGPROGRAM
13 | // Physically based Standard lighting model
14 | #pragma surface surf Standard addshadow
15 | #pragma multi_compile_instancing
16 | #pragma instancing_options procedural:setup
17 |
18 | sampler2D _MainTex;
19 |
20 | struct Input {
21 | float2 uv_MainTex;
22 | };
23 |
24 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
25 | StructuredBuffer positionBuffer;
26 | StructuredBuffer colorBuffer;
27 | #endif
28 |
29 | void setup()
30 | {
31 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
32 | /// Positions are calculated in the compute shader.
33 | /// here we just use them.
34 | float4 position = positionBuffer[unity_InstanceID];
35 | float scale = position.w;
36 |
37 | unity_ObjectToWorld._11_21_31_41 = float4(scale, 0, 0, 0);
38 | unity_ObjectToWorld._12_22_32_42 = float4(0, scale, 0, 0);
39 | unity_ObjectToWorld._13_23_33_43 = float4(0, 0, scale, 0);
40 | unity_ObjectToWorld._14_24_34_44 = float4(position.xyz, 1);
41 | unity_WorldToObject = unity_ObjectToWorld;
42 | unity_WorldToObject._14_24_34 *= -1;
43 | unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
44 | #endif
45 | }
46 |
47 | half _Glossiness;
48 | half _Metallic;
49 |
50 | void surf(Input IN, inout SurfaceOutputStandard o)
51 | {
52 | float4 col = 1.0f;
53 |
54 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
55 | col = colorBuffer[unity_InstanceID];
56 | #else
57 | col = float4(0, 0, 1, 1);
58 | #endif
59 | fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * col;
60 | o.Albedo = c.rgb;
61 | o.Metallic = _Metallic;
62 | o.Smoothness = _Glossiness;
63 | o.Alpha = c.a;
64 | }
65 | ENDCG
66 | }
67 | FallBack "Diffuse"
68 | }
69 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeSurfaceShader.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 311a9917696a65246b07034b0f71d336
3 | timeCreated: 1481683330
4 | licenseType: Pro
5 | ShaderImporter:
6 | defaultTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeTest.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeTest.mat
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectCompute/InstancedIndirectComputeTest.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 782c69a42fb2ab743ac6fa696c8a2e26
3 | timeCreated: 1481683451
4 | licenseType: Pro
5 | NativeFormatImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9abacd4c603193f48aacbb65cec9a28b
3 | folderAsset: yes
4 | timeCreated: 1481682941
5 | licenseType: Pro
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/Floor.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/Floor.mat
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/Floor.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0a72a31b07277f7449c3b1ab27e785fa
3 | timeCreated: 1481766471
4 | licenseType: Pro
5 | NativeFormatImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectExample.cs:
--------------------------------------------------------------------------------
1 | // https://docs.unity3d.com/560/Documentation/ScriptReference/Graphics.DrawMeshInstancedIndirect.html
2 |
3 | using UnityEngine;
4 |
5 | public class InstancedIndirectExample : MonoBehaviour
6 | {
7 | public int instanceCount = 100000;
8 | public Mesh instanceMesh;
9 | public Material instanceMaterial;
10 |
11 | private int cachedInstanceCount = -1;
12 | private ComputeBuffer positionBuffer;
13 | private ComputeBuffer argsBuffer;
14 | private ComputeBuffer colorBuffer;
15 |
16 | private uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
17 |
18 | void Start()
19 | {
20 | argsBuffer = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments);
21 | UpdateBuffers();
22 | }
23 |
24 | void Update()
25 | {
26 | // Update starting position buffer
27 | if (cachedInstanceCount != instanceCount) UpdateBuffers();
28 |
29 | // Pad input
30 | if (Input.GetAxisRaw("Horizontal") != 0.0f) instanceCount = (int)Mathf.Clamp(instanceCount + Input.GetAxis("Horizontal") * 40000, 1.0f, 5000000.0f);
31 |
32 | // Render
33 | // instanceMaterial.SetBuffer("positionBuffer", positionBuffer);
34 | Graphics.DrawMeshInstancedIndirect(instanceMesh, 0, instanceMaterial, new Bounds(Vector3.zero, new Vector3(100.0f, 100.0f, 100.0f)), argsBuffer);
35 | }
36 |
37 | void OnGUI()
38 | {
39 | GUI.Label(new Rect(265, 12, 200, 30), "Instance Count: " + instanceCount.ToString("N0"));
40 | instanceCount = (int)GUI.HorizontalSlider(new Rect(25, 20, 200, 30), (float)instanceCount, 1.0f, 5000000.0f);
41 | }
42 |
43 | void UpdateBuffers()
44 | {
45 | if ( instanceCount < 1 ) instanceCount = 1;
46 |
47 | // Positions & Colors
48 | if (positionBuffer != null) positionBuffer.Release();
49 | if (colorBuffer != null) colorBuffer.Release();
50 |
51 | positionBuffer = new ComputeBuffer(instanceCount, 16);
52 | colorBuffer = new ComputeBuffer(instanceCount, 4*4);
53 |
54 | Vector4[] positions = new Vector4[instanceCount];
55 | Vector4[] colors = new Vector4[instanceCount];
56 |
57 | for (int i=0; i < instanceCount; i++)
58 | {
59 | float angle = Random.Range(0.0f, Mathf.PI * 2.0f);
60 | float distance = Random.Range(20.0f, 100.0f);
61 | float height = Random.Range(-2.0f, 2.0f);
62 | float size = Random.Range(0.05f, 0.25f);
63 | positions[i] = new Vector4(Mathf.Sin(angle) * distance, height, Mathf.Cos(angle) * distance, size);
64 | colors[i] = new Vector4( Random.value, Random.value, Random.value, 1f );
65 | }
66 |
67 | positionBuffer.SetData(positions);
68 | colorBuffer.SetData(colors);
69 |
70 | instanceMaterial.SetBuffer("positionBuffer", positionBuffer);
71 | instanceMaterial.SetBuffer("colorBuffer", colorBuffer);
72 |
73 | // indirect args
74 | uint numIndices = (instanceMesh != null) ? (uint)instanceMesh.GetIndexCount(0) : 0;
75 | args[0] = numIndices;
76 | args[1] = (uint)instanceCount;
77 | argsBuffer.SetData(args);
78 |
79 | cachedInstanceCount = instanceCount;
80 | }
81 |
82 | void OnDisable()
83 | {
84 | if (positionBuffer != null) positionBuffer.Release();
85 | positionBuffer = null;
86 |
87 | if (colorBuffer != null) colorBuffer.Release();
88 | colorBuffer = null;
89 |
90 | if (argsBuffer != null) argsBuffer.Release();
91 | argsBuffer = null;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectExample.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 93f8ec55e72f462458e09232944f33c1
3 | timeCreated: 1481682952
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectExample.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectExample.unity
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectExample.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d94c05110437ffe408a2ee32769362b7
3 | timeCreated: 1481683507
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectSurfaceShader.shader:
--------------------------------------------------------------------------------
1 | Shader "Instanced/InstancedIndirect"
2 | {
3 | Properties{
4 | _MainTex("Albedo (RGB)", 2D) = "white" {}
5 | _Glossiness("Smoothness", Range(0,1)) = 0.5
6 | _Metallic("Metallic", Range(0,1)) = 0.0
7 | }
8 | SubShader{
9 | Tags{ "RenderType" = "Opaque" }
10 | LOD 200
11 |
12 | CGPROGRAM
13 | // Physically based Standard lighting model
14 | #pragma surface surf Standard addshadow
15 | #pragma multi_compile_instancing
16 | #pragma instancing_options procedural:setup
17 |
18 | sampler2D _MainTex;
19 |
20 | struct Input {
21 | float2 uv_MainTex;
22 | };
23 |
24 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
25 | StructuredBuffer positionBuffer;
26 | StructuredBuffer colorBuffer;
27 | #endif
28 |
29 |
30 | void rotate2D(inout float2 v, float r)
31 | {
32 | float s, c;
33 | sincos(r, s, c);
34 | v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
35 | }
36 |
37 | void setup()
38 | {
39 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
40 | float4 data = positionBuffer[unity_InstanceID];
41 |
42 | float rotation = data.w * data.w * _Time.y * 0.5f;
43 | rotate2D(data.xz, rotation);
44 |
45 | unity_ObjectToWorld._11_21_31_41 = float4(data.w, 0, 0, 0);
46 | unity_ObjectToWorld._12_22_32_42 = float4(0, data.w, 0, 0);
47 | unity_ObjectToWorld._13_23_33_43 = float4(0, 0, data.w, 0);
48 | unity_ObjectToWorld._14_24_34_44 = float4(data.xyz, 1);
49 | unity_WorldToObject = unity_ObjectToWorld;
50 | unity_WorldToObject._14_24_34 *= -1;
51 | unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
52 | #endif
53 | }
54 |
55 | half _Glossiness;
56 | half _Metallic;
57 |
58 | void surf(Input IN, inout SurfaceOutputStandard o)
59 | {
60 | float4 col = 1.0f;
61 |
62 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
63 | //col.gb = (float)(unity_InstanceID % 256) / 255.0f;
64 | col = colorBuffer[unity_InstanceID];
65 | #else
66 | //col.gb = float4(0, 0, 1, 1);
67 | col = float4(0, 0, 1, 1);
68 | #endif
69 |
70 |
71 |
72 | fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * col;
73 | o.Albedo = c.rgb;
74 | o.Metallic = _Metallic;
75 | o.Smoothness = _Glossiness;
76 | o.Alpha = c.a;
77 | }
78 | ENDCG
79 | }
80 | FallBack "Diffuse"
81 | }
82 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectSurfaceShader.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 971e564f0c289ad49b0cdce97a9daf38
3 | timeCreated: 1481683330
4 | licenseType: Pro
5 | ShaderImporter:
6 | defaultTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectTest.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectTest.mat
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectExample/InstancedIndirectTest.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0a0f2521dca606b47b5a8ece5d77aadf
3 | timeCreated: 1481683451
4 | licenseType: Pro
5 | NativeFormatImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 38754f0d2a2e3b744af39dd6fae2aae4
3 | folderAsset: yes
4 | timeCreated: 1488639118
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBuffer.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEngine.Rendering;
3 |
4 | ///
5 | /// This demo shows the use of the procedural instancing features to render objects
6 | /// without need of any position buffer. The values are calculated direclty inside the
7 | /// shader.
8 | /// The color buffer is used for debug only.
9 | ///
10 | public class InstancedIndirectNoBuffer : MonoBehaviour
11 | {
12 | public int gridDim = 1000;
13 | public int instanceCount = 0;
14 | public Mesh instanceMesh;
15 | public Material instanceMaterial;
16 |
17 | public ShadowCastingMode castShadows = ShadowCastingMode.Off;
18 | public bool receiveShadows = false;
19 |
20 | private ComputeBuffer argsBuffer;
21 | private ComputeBuffer colorBuffer;
22 |
23 | private uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
24 |
25 | void Start()
26 | {
27 | instanceCount = gridDim * gridDim;
28 | argsBuffer = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments);
29 | CreateBuffers();
30 | }
31 |
32 | void Update()
33 | {
34 | Graphics.DrawMeshInstancedIndirect(instanceMesh, 0, instanceMaterial, instanceMesh.bounds, argsBuffer, 0, null, castShadows, receiveShadows);
35 | }
36 |
37 | void CreateBuffers()
38 | {
39 | if ( instanceCount < 1 ) instanceCount = 1;
40 |
41 | //instanceCount = Mathf.ClosestPowerOfTwo(instanceCount);
42 | instanceMesh.bounds = new Bounds(Vector3.zero, Vector3.one * 10000f); //avoid culling
43 |
44 | /// Colors - for debug only
45 | if (colorBuffer != null) colorBuffer.Release();
46 |
47 | colorBuffer = new ComputeBuffer(instanceCount, 16);
48 |
49 | Vector4[] colors = new Vector4[instanceCount];
50 | for (int i = 0; i < instanceCount; i++)
51 | colors[i] = Random.ColorHSV();
52 |
53 | colorBuffer.SetData(colors);
54 |
55 | instanceMaterial.SetBuffer("colorBuffer", colorBuffer);
56 |
57 | // indirect args
58 | uint numIndices = (instanceMesh != null) ? (uint)instanceMesh.GetIndexCount(0) : 0;
59 | args[0] = numIndices;
60 | args[1] = (uint)instanceCount;
61 | argsBuffer.SetData(args);
62 |
63 | Shader.SetGlobalFloat("_Dim", gridDim);
64 | }
65 |
66 | void OnDisable()
67 | {
68 | if (colorBuffer != null) colorBuffer.Release();
69 | colorBuffer = null;
70 |
71 | if (argsBuffer != null) argsBuffer.Release();
72 | argsBuffer = null;
73 | }
74 |
75 | void OnGUI()
76 | {
77 | GUI.Label(new Rect(265, 12, 200, 30), "Instance Count: " + instanceCount.ToString("N0"));
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBuffer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 20f1e530bbaf9124281b78e6988b83f8
3 | timeCreated: 1481682952
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBuffer.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBuffer.unity
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBuffer.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b70673dfc77f1de46a1df6867043cb24
3 | timeCreated: 1481683507
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBufferSurfaceShader.shader:
--------------------------------------------------------------------------------
1 | Shader "Instanced/InstancedIndirectNoBuffer"
2 | {
3 | Properties{
4 | _MainTex("Albedo (RGB)", 2D) = "white" {}
5 | _Glossiness("Smoothness", Range(0,1)) = 0.5
6 | _Metallic("Metallic", Range(0,1)) = 0.0
7 | }
8 | SubShader{
9 | Tags{ "RenderType" = "Opaque" }
10 | LOD 200
11 |
12 | CGPROGRAM
13 | // Physically based Standard lighting model
14 | #pragma surface surf Standard addshadow
15 | #pragma multi_compile_instancing
16 | #pragma instancing_options procedural:setup
17 |
18 | sampler2D _MainTex;
19 |
20 | struct Input {
21 | float2 uv_MainTex;
22 | };
23 |
24 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
25 | StructuredBuffer colorBuffer;
26 | #endif
27 | float _Dim;
28 |
29 | float rand(in float2 uv)
30 | {
31 | float2 noise = (frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453));
32 | return abs(noise.x + noise.y) * 0.5;
33 | }
34 |
35 | void rotate2D(inout float2 v, float r)
36 | {
37 | float s, c;
38 | sincos(r, s, c);
39 | v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
40 | }
41 |
42 | void setup()
43 | {
44 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
45 | // this uv assumes the # of instances is _Dim * _Dim.
46 | // so we calculate the uv inside a grid of _Dim x _Dim elements.
47 | float2 uv = float2( floor(unity_InstanceID / _Dim) / _Dim, (unity_InstanceID % (int)_Dim) / _Dim);
48 | // in this case, _Dim can be replaced by the size in the world
49 | float4 position = float4((uv.x - 0.5) * _Dim, 0, (uv.y - 0.5) * _Dim, rand(uv));
50 | float scale = position.w;
51 |
52 | float rotation = scale * scale * _Time.y * 0.5f;
53 | rotate2D(position.xz, rotation);
54 |
55 | unity_ObjectToWorld._11_21_31_41 = float4(scale, 0, 0, 0);
56 | unity_ObjectToWorld._12_22_32_42 = float4(0, scale, 0, 0);
57 | unity_ObjectToWorld._13_23_33_43 = float4(0, 0, scale, 0);
58 | unity_ObjectToWorld._14_24_34_44 = float4(position.xyz, 1);
59 | unity_WorldToObject = unity_ObjectToWorld;
60 | unity_WorldToObject._14_24_34 *= -1;
61 | unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
62 | #endif
63 | }
64 |
65 | half _Glossiness;
66 | half _Metallic;
67 |
68 | void surf(Input IN, inout SurfaceOutputStandard o)
69 | {
70 | float4 col = 1.0f;
71 |
72 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
73 | col = colorBuffer[unity_InstanceID];
74 | #else
75 | col = float4(0, 0, 1, 1);
76 | #endif
77 | fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * col;
78 | o.Albedo = c.rgb;
79 | o.Metallic = _Metallic;
80 | o.Smoothness = _Glossiness;
81 | o.Alpha = c.a;
82 | }
83 | ENDCG
84 | }
85 | FallBack "Diffuse"
86 | }
87 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBufferSurfaceShader.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 971741a1304bb2b41b2e72e31af3d084
3 | timeCreated: 1481683330
4 | licenseType: Pro
5 | ShaderImporter:
6 | defaultTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBufferTest.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBufferTest.mat
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectNoBuffer/InstancedIndirectNoBufferTest.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2eb1300652a74a44285e06810ba59e1e
3 | timeCreated: 1481683451
4 | licenseType: Pro
5 | NativeFormatImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 16ffa2ef1b97d9444918d2a2d97add8a
3 | folderAsset: yes
4 | timeCreated: 1489672517
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using UnityEngine.Rendering;
3 |
4 | ///
5 | /// This demo shows the use of the procedural instancing features to render objects
6 | /// without need of any position buffer. The values are calculated direclty inside the
7 | /// shader.
8 | /// Shadowing is broken when more than one DrawMeshInstancedIndirect is made.
9 | /// - Tested with different materials, same materials.
10 | /// - Different bounds settings.
11 | /// - Same args buffer (for different draw calls with same mesh).
12 | /// - Different args buffers (with same mesh, and with different meshes).
13 | /// WorkAround: adding an unique mpb per draw call apparently works!
14 | ///
15 | /// The color buffer is used for debug only.
16 | ///
17 | public class InstancedIndirectShadowsIssue : MonoBehaviour
18 | {
19 | public int gridDim = 1000;
20 | public int instanceCount = 0;
21 | public Material instanceMaterial;
22 |
23 | public ShadowCastingMode castShadows = ShadowCastingMode.Off;
24 | public bool receiveShadows = false;
25 |
26 | private ComputeBuffer colorBuffer;
27 |
28 | private uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
29 | private Material[] materials;
30 |
31 | public Mesh[] meshes;
32 | private ComputeBuffer[] argsBuffers;
33 | public Shader shader;
34 |
35 | public bool[] render;
36 |
37 | MaterialPropertyBlock[] mpbs;
38 |
39 | void Start()
40 | {
41 | instanceCount = gridDim * gridDim;
42 |
43 | argsBuffers = new ComputeBuffer[meshes.Length];
44 | for (int i = 0; i < meshes.Length; i++)
45 | {
46 | argsBuffers[i] = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments);
47 | }
48 |
49 | mpbs = new MaterialPropertyBlock[meshes.Length];
50 | materials = new Material[meshes.Length];
51 | for (int i = 0; i < materials.Length; i++)
52 | {
53 | materials[i] = new Material(instanceMaterial);
54 | mpbs[i] = new MaterialPropertyBlock();
55 | }
56 |
57 | CreateBuffers();
58 | }
59 |
60 | void Update()
61 | {
62 |
63 | for (int i = 0; i < meshes.Length; i++)
64 | {
65 | materials[i].SetFloat("_Dim", gridDim);
66 | materials[i].SetVector("_Pos", new Vector4(i * (gridDim + 10), 0, 0, 0));
67 | materials[i].SetBuffer("colorBuffer", colorBuffer);
68 |
69 | /// this is the magic line. Uncomment this for shadows!!
70 | mpbs[i].SetFloat("_Bla", (float)i);
71 |
72 | if (render[i])
73 | Graphics.DrawMeshInstancedIndirect(meshes[i], 0, materials[i], meshes[i].bounds, argsBuffers[i], 0, mpbs[i], castShadows, receiveShadows);
74 | }
75 | }
76 |
77 | void CreateBuffers()
78 | {
79 | /// Colors - for debug only
80 | if (colorBuffer != null)
81 | colorBuffer.Release();
82 |
83 | colorBuffer = new ComputeBuffer(instanceCount, 16);
84 |
85 | Vector4[] colors = new Vector4[instanceCount];
86 | for (int i = 0; i < instanceCount; i++)
87 | colors[i] = Random.ColorHSV();
88 |
89 | colorBuffer.SetData(colors);
90 |
91 | // avoid culling
92 | for (int i = 0; i < meshes.Length; i++)
93 | {
94 | meshes[i].bounds = new Bounds(Vector3.zero, Vector3.one * 10000f);
95 | }
96 |
97 | // indirect args
98 | for (int i = 0; i < argsBuffers.Length; i++)
99 | {
100 | args[0] = meshes[i].GetIndexCount(0);
101 | args[1] = (uint)instanceCount;
102 | argsBuffers[i].SetData(args);
103 | }
104 | }
105 |
106 | void OnDestroy()
107 | {
108 | if (colorBuffer != null)
109 | colorBuffer.Release();
110 | colorBuffer = null;
111 |
112 | for (int i = 0; i < argsBuffers.Length; i++)
113 | {
114 | if(argsBuffers[i] != null)
115 | argsBuffers[i].Release();
116 | }
117 | argsBuffers = null;
118 | }
119 |
120 | void OnGUI()
121 | {
122 | GUI.Label(new Rect(265, 12, 200, 30), "Instance Count: " + instanceCount.ToString("N0"));
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d44ce7be82416414c93855550ccc2826
3 | timeCreated: 1481682952
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.mat
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.mat.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 17ba879e8a154214db997257eecacd7e
3 | timeCreated: 1481683451
4 | licenseType: Pro
5 | NativeFormatImporter:
6 | mainObjectFileID: -1
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.unity:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.unity
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssue.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 18222df251a1b6842a704bacf05d93f2
3 | timeCreated: 1481683507
4 | licenseType: Pro
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssueSurfaceShader.shader:
--------------------------------------------------------------------------------
1 | Shader "Instanced/InstancedIndirectShadowsIssue"
2 | {
3 | Properties{
4 | _MainTex("Albedo (RGB)", 2D) = "white" {}
5 | _Glossiness("Smoothness", Range(0,1)) = 0.5
6 | _Metallic("Metallic", Range(0,1)) = 0.0
7 | }
8 | SubShader{
9 | Tags{ "RenderType" = "Opaque" }
10 | LOD 200
11 |
12 | CGPROGRAM
13 | // Physically based Standard lighting model
14 | #pragma surface surf Standard addshadow
15 | #pragma multi_compile_instancing
16 | #pragma instancing_options procedural:setup
17 |
18 | sampler2D _MainTex;
19 |
20 | struct Input {
21 | float2 uv_MainTex;
22 | };
23 |
24 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
25 | StructuredBuffer colorBuffer;
26 | #endif
27 | float _Dim;
28 | float4 _Pos;
29 |
30 | float rand(in float2 uv)
31 | {
32 | float2 noise = (frac(sin(dot(uv ,float2(12.9898,78.233)*2.0)) * 43758.5453));
33 | return abs(noise.x + noise.y) * 0.5;
34 | }
35 |
36 | void rotate2D(inout float2 v, float r)
37 | {
38 | float s, c;
39 | sincos(r, s, c);
40 | v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
41 | }
42 |
43 | void setup()
44 | {
45 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
46 | // this uv assumes the # of instances is _Dim * _Dim.
47 | // so we calculate the uv inside a grid of _Dim x _Dim elements.
48 | float2 uv = float2( floor(unity_InstanceID / _Dim) / _Dim, (unity_InstanceID % (int)_Dim) / _Dim);
49 | // in this case, _Dim can be replaced by the size in the world
50 | float4 position = _Pos + float4(uv.x * _Dim * 2, 0, uv.y * _Dim * 2, 1);
51 | float scale = position.w;
52 |
53 | //float rotation = scale * scale * _Time.y * 0.5f;
54 | //rotate2D(position.xz, rotation);
55 |
56 | unity_ObjectToWorld._11_21_31_41 = float4(scale, 0, 0, 0);
57 | unity_ObjectToWorld._12_22_32_42 = float4(0, scale, 0, 0);
58 | unity_ObjectToWorld._13_23_33_43 = float4(0, 0, scale, 0);
59 | unity_ObjectToWorld._14_24_34_44 = float4(position.xyz, 1);
60 | unity_WorldToObject = unity_ObjectToWorld;
61 | unity_WorldToObject._14_24_34 *= -1;
62 | unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
63 | #endif
64 | }
65 |
66 | half _Glossiness;
67 | half _Metallic;
68 |
69 | void surf(Input IN, inout SurfaceOutputStandard o)
70 | {
71 | float4 col = 1.0f;
72 |
73 | #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
74 | col = colorBuffer[unity_InstanceID];
75 | #else
76 | col = float4(0, 0, 1, 1);
77 | #endif
78 | fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * col;
79 | o.Albedo = c.rgb;
80 | o.Metallic = _Metallic;
81 | o.Smoothness = _Glossiness;
82 | o.Alpha = c.a;
83 | }
84 | ENDCG
85 | }
86 | FallBack "Diffuse"
87 | }
88 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/Assets/InstancedIndirectShadowsIssue/InstancedIndirectShadowsIssueSurfaceShader.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: dd0b9ef56a2ba204a8fe7b051dc47feb
3 | timeCreated: 1481683330
4 | licenseType: Pro
5 | ShaderImporter:
6 | defaultTextures: []
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/AudioManager.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/ClusterInputManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/ClusterInputManager.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/DynamicsManager.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/EditorBuildSettings.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/EditorSettings.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/GraphicsSettings.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/InputManager.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/NavMeshAreas.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/NavMeshAreas.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/NetworkManager.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/Physics2DSettings.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/ProjectSettings.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/ProjectVersion.txt:
--------------------------------------------------------------------------------
1 | m_EditorVersion: 2017.2.0f3
2 |
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/QualitySettings.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/TagManager.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/TimeManager.asset
--------------------------------------------------------------------------------
/Demos-DrawMeshInstancedIndirect/ProjectSettings/UnityConnectSettings.asset:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Demos-DrawMeshInstancedIndirect/ProjectSettings/UnityConnectSettings.asset
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Noisecrime
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DrawMeshInstanceIndirect examples.
2 | Exploring the Unity 5.6 DrawMeshInstanceIndirect method to render large numbers of objects.
3 |
4 | ### InstancedIndirectExample
5 | The example on scene InstancedIndirectExample is a slightly expanded version of [Unity's sample](https://docs.unity3d.com/560/Documentation/ScriptReference/Graphics.DrawMeshInstancedIndirect.html) code provided by [noisecrime](https://github.com/noisecrime/Unity-InstancedIndirectExamples). The buffer is created in CPU and the position sampled in GPU. This approach is useful when the positions are static, otherwise the cost of update from CPU is very high.
6 |
7 | ### InstancedIndirectComputeExample
8 | The example on scene InstancedIndirectComputeExample demonstrates the use of Compute Shaders to generate position data. Compute Shaders are specially useful when the buffers need constant update, as the buffer remains in GPU and we can take advantage of many threads to perform the calculations.
9 |
10 | ### InstancedIndirectNoBuffer
11 | The example on scene InstancedIndirectNoBuffer shows how to position the objects on the fly, directly within the shader. This approach eliminates the use of any auxiliar buffer, and positions can be calculated directly in the surface shader. This is very attractive for when the calculations are simple and the number of instances is very high.
12 |
13 | ### InstancedIndirectComputeAppend
14 | The example on scene InstancedIndirectComputeAppend shows how to render instances when the number of elements is not known beforehand.
15 | A compute is dispatched with N threads but not all of them assign values to the position buffer. An AppendStructuredBuffer is used in this case [+info](https://msdn.microsoft.com/en-us/library/windows/desktop/ff471448(v=vs.85).aspx). As the CPU does not know how many instances were created, we use the CopyCount function to update the args buffer that is passed to the DrawMeshInstancedIndirect function.
16 |
17 | ### InstancedIndirectShadowsIssue
18 |
19 | There is an open issue in Unity 5.6b that, when issuing several drawcalls using DrawMeshInstancedIndirect the shadow is broken. The bug was reported [here](https://issuetracker.unity3d.com/issues/drawmeshinstanceindirect-wrong-computebuffer-being-passsed-to-consecutive-drawmesh-calls). A blog post discussing it can be found [here](https://forum.unity3d.com/threads/drawmeshinstancedindirect-example-comments-and-questions.446080/#post-2995966).
20 | Here's the workaround:
21 |
22 | * If you duplicate the shader file, and rename it. Add each duplicate to a different material, it works. Which indicates that Unity is having troubles differentiating among the materials, and is trying to batch them somehow.
23 | * So I had to find a way to force Unity disable whatever it was that was not separating the materials. Creating the material from code (using the shader or the original material) was not working
24 | * The uniforms I was passing with the materials were different from each other, but that didn't do it.
25 | * The only thing left was the MaterialPropertyBlock (which I wasn't using). Setting an empty mpb per draw call also didn't work.
26 | * What did work was to set an unique dummy variable per mpb, so that Unity will have to issue a different call. The variable doesn't even have to be used in the shader.
27 |
28 | for (int i = 0; i < meshes.Length; i++)
29 | {
30 | materials[i].SetFloat("_Dim", gridDim);
31 | .......
32 | /// this is the magic line. Uncomment this for shadows!!
33 | mpbs[i].SetFloat("_Bla", (float)i);
34 | Graphics.DrawMeshInstancedIndirect(meshes[i], 0, materials[i], meshes[i].bounds, argsBuffers[i], 0, mpbs[i], castShadows, receiveShadows);
35 | }
36 |
37 | It is not ideal, but it works!! Image with 4 draw calls (one per different group).
38 |
39 | 
40 |
41 |
42 |
43 | ** NOTE: these are WIP demos.
44 |
45 |
--------------------------------------------------------------------------------
/Untitled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ttvertex/Unity-InstancedIndirectExamples/960604d705bd3f4db09773c07c4b36ac5e8dc295/Untitled.png
--------------------------------------------------------------------------------