using UnityEngine; using UnityEngine.Rendering; using Unity.Profiling; using System.Collections.Generic; using Unity.Collections; namespace Obi { public class ComputeChainRopeRenderSystem : ObiChainRopeRenderSystem { private ComputeShader ropeShader; private int updateKernel; private uint[] args = new uint[5] { 0, 0, 0, 0, 0 }; public ComputeChainRopeRenderSystem(ObiSolver solver) : base(solver) { ropeShader = GameObject.Instantiate(Resources.Load("Compute/RopeChainRendering")); updateKernel = ropeShader.FindKernel("UpdateChainMesh"); } protected override void CloseBatches() { // Initialize each batch: for (int i = 0; i < batchList.Count; ++i) batchList[i].Initialize(true); } public override void Setup() { base.Setup(); rendererData.AsComputeBuffer(); chunkData.AsComputeBuffer(); modifiers.SafeAsComputeBuffer(); elements.AsComputeBuffer(); instanceTransforms.AsComputeBuffer(); invInstanceTransforms.AsComputeBuffer(); instanceColors.AsComputeBuffer(); } public override void Render() { using (m_RenderMarker.Auto()) { var computeSolver = m_Solver.implementation as ComputeSolverImpl; if (computeSolver.renderablePositionsBuffer != null && computeSolver.renderablePositionsBuffer.count > 0 && elements.count > 0) { ropeShader.SetBuffer(updateKernel, "rendererData", rendererData.computeBuffer); ropeShader.SetBuffer(updateKernel, "chunksData", chunkData.computeBuffer); ropeShader.SetBuffer(updateKernel, "modifiers", modifiers.computeBuffer); ropeShader.SetBuffer(updateKernel, "elements", elements.computeBuffer); ropeShader.SetBuffer(updateKernel, "renderablePositions", computeSolver.renderablePositionsBuffer); ropeShader.SetBuffer(updateKernel, "renderableOrientations", computeSolver.renderableOrientationsBuffer); ropeShader.SetBuffer(updateKernel, "principalRadii", computeSolver.renderableRadiiBuffer); ropeShader.SetBuffer(updateKernel, "colors", computeSolver.colorsBuffer); ropeShader.SetBuffer(updateKernel, "instanceTransforms", instanceTransforms.computeBuffer); ropeShader.SetBuffer(updateKernel, "invInstanceTransforms", invInstanceTransforms.computeBuffer); ropeShader.SetBuffer(updateKernel, "instanceColors", instanceColors.computeBuffer); ropeShader.SetMatrix("solverToWorld", m_Solver.transform.localToWorldMatrix); ropeShader.SetInt("chunkCount", chunkData.count); int threadGroups = ComputeMath.ThreadGroupCount(chunkData.count, 32); ropeShader.Dispatch(updateKernel, threadGroups, 1, 1); MaterialPropertyBlock mpb = new MaterialPropertyBlock(); mpb.SetBuffer("_InstanceTransforms", instanceTransforms.computeBuffer); mpb.SetBuffer("_InvInstanceTransforms", invInstanceTransforms.computeBuffer); mpb.SetBuffer("_Colors", instanceColors.computeBuffer); for (int i = 0; i < batchList.Count; ++i) { var batch = batchList[i]; if (batch.mesh == null) continue; args[0] = (uint)batch.mesh.GetIndexCount(0); args[1] = (uint)batch.instanceCount; args[2] = (uint)batch.mesh.GetIndexStart(0); args[3] = (uint)batch.mesh.GetBaseVertex(0); args[4] = (uint)batch.firstInstance; batch.argsBuffer.SetData(args); var rp = batch.renderParams; rp.material = batch.material; rp.worldBounds = m_Solver.bounds; rp.matProps = mpb; Graphics.RenderMeshIndirect(rp, batch.mesh, batch.argsBuffer); } } } } } }