namespace Environment.Instancing
{
using UnityEngine;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
///
/// Data as seen on GPU. Exact same struct should be defined there.
///
public struct InstanceData
{
public Matrix4x4 TRS;
public Vector3 Normal;
}
///
/// Contains the needed bakend information for instancing with Graphics.RenderMeshIndirect().
///
public class InstancingConfiguration
{
public Mesh Mesh;
public Material Material;
public MaterialPropertyBlock MaterialPropertyBlock;
public ComputeBuffer CommandBuffer;
public ComputeBuffer DataBuffer;
///
/// Initializes new instancing information.
///
public InstancingConfiguration(InstancingSettings settings, IEnumerable data, string shaderBufferParameter)
{
this.Mesh = settings.Mesh;
this.Material = settings.Material;
this.DataBuffer = new ComputeBuffer(data.Count(), Marshal.SizeOf());
this.DataBuffer.SetData(data.ToArray());
var commandArguments = new uint[5];
commandArguments[0] = settings.Mesh.GetIndexCount(0);
commandArguments[1] = (uint)data.Count();
this.CommandBuffer = new ComputeBuffer(5, sizeof(uint), ComputeBufferType.IndirectArguments);
this.CommandBuffer.SetData(commandArguments);
this.MaterialPropertyBlock = new MaterialPropertyBlock();
this.MaterialPropertyBlock.SetBuffer(shaderBufferParameter, this.DataBuffer);
}
///
/// Frees the memory of this configuration from the GPU.
///
public void FreeMemory()
{
this.CommandBuffer?.Release();
this.CommandBuffer = null;
this.DataBuffer?.Release();
this.DataBuffer = null;
}
}
}
/*
* if Unity ever supports Graphics.RenderMeshIndirect() with Shader Graph shaded instances. This can be used to upgrade.
namespace Environment.Instancing
{
using UnityEngine;
using System.Runtime.InteropServices;
///
/// Contains the needed bakend information for instancing with Graphics.RenderMeshIndirect().
///
public class InstancingInfo
{
public GraphicsBuffer GraphicsBuffer;
public MaterialPropertyBlock MaterialPropertyBlock;
///
/// Initializes new instancing information.
///
public InstancingInfo(T[] data, string shaderBufferParameter)
{
// For structured graphics buffer there has to be an equivalnt struct in hlsl
this.GraphicsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, data.Length, Marshal.SizeOf());
this.MaterialPropertyBlock = new MaterialPropertyBlock();
this.MaterialPropertyBlock.SetBuffer(shaderBufferParameter, this.GraphicsBuffer);
}
}
}
*/