Created
May 7, 2022 17:11
-
-
Save EliCDavis/d8f69f42e01a953631c86bb336868649 to your computer and use it in GitHub Desktop.
Random Instancing Garbage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class DrawMeshInstancedDemo : MonoBehaviour { | |
[SerializeField] | |
private Color color1; | |
[SerializeField] | |
private Color color2; | |
public int population; | |
public Vector3 range; | |
public Vector3 sizeMin; | |
public Vector3 sizeMax; | |
public Material material; | |
private Matrix4x4[] matrices; | |
private MaterialPropertyBlock block; | |
[SerializeField] | |
private Mesh mesh; | |
[SerializeField] | |
private Mesh mesh2; | |
private void Setup() { | |
// Mesh mesh = CreateQuad(); | |
// this.mesh = mesh; | |
matrices = new Matrix4x4[population]; | |
Vector4[] colors = new Vector4[population]; | |
block = new MaterialPropertyBlock(); | |
for (int i = 0; i < population; i++) { | |
// Build matrix. | |
Vector3 position = new Vector3(Random.Range(-range.x, range.x), Random.Range(-range.y, range.y), Random.Range(-range.z, range.z)); | |
position.y = Terrain.activeTerrain.SampleHeight(position) - 1.3f; | |
Quaternion rotation = Quaternion.Euler(Random.Range(-4, 4), Random.Range(-180, 180), Random.Range(-4, 4)); | |
var sizeRange = sizeMax - sizeMin; | |
Vector3 scale = sizeMin + new Vector3(Random.Range(0, sizeRange.x), Random.Range(0, sizeRange.y), Random.Range(0, sizeRange.z)); | |
var mat = Matrix4x4.TRS(position, rotation, scale); | |
matrices[i] = mat; | |
colors[i] = Color.Lerp(Color.red, Color.blue, Random.value); | |
} | |
// Custom shader needed to read these!! | |
block.SetVectorArray("_Colors", colors); | |
} | |
// private Mesh CreateQuad(float width = 1f, float height = 1f) { | |
// // Create a quad mesh. | |
// // See source for implementation. | |
// } | |
private void Start() { | |
Setup(); | |
} | |
private void Update() { | |
// Draw a bunch of meshes each frame. | |
Graphics.DrawMeshInstanced(mesh, 0, material, matrices, population, block); | |
Graphics.DrawMeshInstanced(mesh2, 0, material, matrices, population, block); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class DrawMeshInstancedIndirectDemo : MonoBehaviour | |
{ | |
[SerializeField] | |
private Color color1; | |
[SerializeField] | |
private Color color2; | |
public int population; | |
public Vector3 range; | |
public Vector3 sizeMin; | |
public Vector3 sizeMax; | |
public Material material; | |
private ComputeBuffer meshPropertiesBuffer; | |
private ComputeBuffer argsBuffer; | |
[SerializeField] | |
private Mesh mesh; | |
private Bounds bounds; | |
private struct MeshProperties | |
{ | |
public Matrix4x4 mat; | |
public Vector4 color; | |
public static int Size() | |
{ | |
return | |
sizeof(float) * 4 * 4 + // matrix; | |
sizeof(float) * 4; // color; | |
} | |
} | |
private void Setup() | |
{ | |
// Boundary surrounding the meshes we will be drawing. Used for occlusion. | |
bounds = new Bounds(transform.position, Vector3.one + range); | |
InitializeBuffers(); | |
} | |
private void InitializeBuffers() | |
{ | |
uint[] args = new uint[5] { 0, 0, 0, 0, 0 }; | |
args[0] = (uint)mesh.GetIndexCount(0); | |
args[1] = (uint)population; | |
args[2] = (uint)mesh.GetIndexStart(0); | |
args[3] = (uint)mesh.GetBaseVertex(0); | |
argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments); | |
argsBuffer.SetData(args); | |
// Initialize buffer with the given population. | |
MeshProperties[] properties = new MeshProperties[population]; | |
for (int i = 0; i < population; i++) | |
{ | |
MeshProperties props = new MeshProperties(); | |
Vector3 position = new Vector3(Random.Range(-range.x, range.x), Random.Range(-range.y, range.y), Random.Range(-range.z, range.z)); | |
position.y = Terrain.activeTerrain.SampleHeight(position) - 1.3f; | |
Quaternion rotation = Quaternion.Euler(Random.Range(-4, 4), Random.Range(-180, 180), Random.Range(-4, 4)); | |
var sizeRange = sizeMax - sizeMin; | |
Vector3 scale = sizeMin + new Vector3(Random.Range(0, sizeRange.x), Random.Range(0, sizeRange.y), Random.Range(0, sizeRange.z)); | |
props.mat = Matrix4x4.TRS(position, rotation, scale); | |
props.color = Color.Lerp(color1, color2, Random.value); | |
properties[i] = props; | |
} | |
meshPropertiesBuffer = new ComputeBuffer(population, MeshProperties.Size()); | |
meshPropertiesBuffer.SetData(properties); | |
material.SetBuffer("_Properties", meshPropertiesBuffer); | |
} | |
private void Start() | |
{ | |
Setup(); | |
} | |
private void Update() | |
{ | |
Graphics.DrawMeshInstancedIndirect(mesh, 0, material, bounds, argsBuffer); | |
} | |
private void OnDisable() | |
{ | |
// Release gracefully. | |
if (meshPropertiesBuffer != null) | |
{ | |
meshPropertiesBuffer.Release(); | |
} | |
meshPropertiesBuffer = null; | |
if (argsBuffer != null) | |
{ | |
argsBuffer.Release(); | |
} | |
argsBuffer = null; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Custom/InstancedIndirectColor" { | |
Properties | |
{ | |
_MainTex ("_MainTex (RGBA)", 2D) = "white" {} | |
} | |
SubShader { | |
Tags { "RenderType" = "Opaque" } | |
Pass { | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
// #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" | |
#include "UnityCG.cginc" | |
struct appdata_t { | |
float4 vertex : POSITION; | |
float4 color : COLOR; | |
float2 uv : TEXCOORD0; | |
}; | |
struct v2f { | |
float4 vertex : SV_POSITION; | |
fixed4 color : COLOR; | |
float2 uv : TEXCOORD0; | |
}; | |
struct MeshProperties { | |
float4x4 mat; | |
float4 color; | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
StructuredBuffer<MeshProperties> _Properties; | |
v2f vert(appdata_t i, uint instanceID: SV_InstanceID) { | |
v2f o; | |
float4 pos = mul(_Properties[instanceID].mat, i.vertex); | |
o.vertex = UnityObjectToClipPos(pos); | |
o.color = _Properties[instanceID].color; | |
o.uv = TRANSFORM_TEX(i.uv, _MainTex); | |
return o; | |
} | |
fixed4 frag(v2f i) : SV_Target { | |
float4 col = tex2D(_MainTex, i.uv); | |
return col * i.color; | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment