111
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user