111 lines
2.8 KiB
C#
111 lines
2.8 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
public class GrassTest : MonoBehaviour
|
|
{
|
|
public Mesh mesh;
|
|
public Material material;
|
|
public Bounds bounds;
|
|
public float scaleMult;
|
|
public ShadowCastingMode shadowCastingMode;
|
|
public bool isReceiveShadow;
|
|
|
|
private ComputeBuffer instDataBuffer;
|
|
private ComputeBuffer argsBuffer;
|
|
|
|
|
|
// Mesh Properties struct to be read from the GPU.
|
|
// Size() is a convenience funciton which returns the stride of the struct.
|
|
public Transform root;
|
|
List<InstData> dataInfors = new List<InstData>();
|
|
|
|
private struct InstData
|
|
{
|
|
public Vector3 pos;
|
|
public Vector3 angle;
|
|
public Vector3 scale;
|
|
|
|
//
|
|
public static int GetNum()
|
|
{
|
|
return sizeof(float) * 3 + sizeof(float) * 3 + sizeof(float) * 3;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void Start()
|
|
{
|
|
GetDataInfors();
|
|
InitializeBuffers();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
Graphics.DrawMeshInstancedIndirect(mesh, 0, material, bounds, argsBuffer, 0, null, shadowCastingMode, isReceiveShadow, LayerMask.NameToLayer("Instance"));
|
|
}
|
|
|
|
|
|
|
|
void GetDataInfors()
|
|
{
|
|
foreach (Transform t in root.GetComponentInChildren<Transform>())
|
|
{
|
|
InstData instData = new InstData();
|
|
instData.pos = t.position;
|
|
instData.angle = t.eulerAngles;
|
|
instData.scale = t.localScale * scaleMult;
|
|
dataInfors.Add(instData);
|
|
|
|
//
|
|
t.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void InitializeBuffers()
|
|
{
|
|
// Argument buffer used by DrawMeshInstancedIndirect.
|
|
uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
|
|
// Arguments for drawing mesh.
|
|
// 0 == number of triangle indices, 1 == population, others are only relevant if drawing submeshes.
|
|
args[0] = (uint)mesh.GetIndexCount(0);
|
|
args[1] = (uint)dataInfors.Count;
|
|
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.
|
|
instDataBuffer = new ComputeBuffer(dataInfors.Count, InstData.GetNum());
|
|
instDataBuffer.SetData(dataInfors);
|
|
material = Instantiate(material);
|
|
material.SetBuffer("_InstDataBuffer", instDataBuffer);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void OnDisable()
|
|
{
|
|
// Release gracefully.
|
|
if (instDataBuffer != null)
|
|
{
|
|
instDataBuffer.Release();
|
|
}
|
|
instDataBuffer = null;
|
|
|
|
if (argsBuffer != null)
|
|
{
|
|
argsBuffer.Release();
|
|
}
|
|
argsBuffer = null;
|
|
}
|
|
} |