更新obi到7.1

This commit is contained in:
Bob.Song
2025-11-03 11:53:45 +08:00
parent d12e1bc495
commit 7cf7f545bc
1161 changed files with 158924 additions and 37802 deletions

View File

@@ -0,0 +1,107 @@
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<ComputeShader>("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<ChainRendererData>();
chunkData.AsComputeBuffer<ChunkData>();
modifiers.SafeAsComputeBuffer<ObiRopeChainRenderer.LinkModifier>();
elements.AsComputeBuffer<Vector2Int>();
instanceTransforms.AsComputeBuffer<Matrix4x4>();
invInstanceTransforms.AsComputeBuffer<Matrix4x4>();
instanceColors.AsComputeBuffer<Vector4>();
}
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);
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe4c45599ea584be2a1b122fbe7d0ec6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,101 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace Obi
{
public class ComputeExtrudedRopeRenderSystem : ObiExtrudedRopeRenderSystem
{
private ComputeShader ropeShader;
private int updateKernel;
public ComputeExtrudedRopeRenderSystem(ObiSolver solver) : base(solver)
{
ropeShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/RopeExtrudedRendering"));
updateKernel = ropeShader.FindKernel("UpdateRopeMesh");
}
public override void Setup()
{
base.Setup();
// Initialize each batch:
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Initialize(layout, true);
sectionData.AsComputeBuffer<Vector2>();
sectionOffsets.AsComputeBuffer<int>();
sectionIndices.AsComputeBuffer<int>();
vertexOffsets.AsComputeBuffer<int>();
triangleOffsets.AsComputeBuffer<int>();
triangleCounts.AsComputeBuffer<int>();
pathSmootherIndices.AsComputeBuffer<int>();
rendererData.AsComputeBuffer<BurstExtrudedMeshData>();
pathSmootherSystem.chunkOffsets.AsComputeBuffer<int>();
}
public override void Render()
{
using (m_RenderMarker.Auto())
{
if (pathSmootherSystem == null)
return;
// Single array: Cannot merge into a single vertices array, otherwise we would need to bring back to CPU for passing indices to each mesh.
// Individual meshes: Cannot do each renderer independently (like we do with cloth) since each rope is done sequentially, would not parallelize at all.
// Batches: 1 mesh per batch: best approach, but 1) bounds must be calculated per or solver, so we can only cull entire solver. Culling happens on the CPU, cannot bring back bounds from the CPU.
// Cloth and Softbodies are rendered manually, particles are too. So Ropes could too.
// In Burst, we need merge all cloth mesh data into array for parallel processing, without using one schedule() per mesh.
// So instead of writing slices of mesh data back to their original meshes, let's create one mesh per batch and draw it ourselves.
// Basically the same as with ropes.
if (pathSmootherSystem.chunkOffsets != null && pathSmootherSystem.chunkOffsets.count > 0)
{
ropeShader.SetBuffer(updateKernel, "pathSmootherIndices", pathSmootherIndices.computeBuffer);
ropeShader.SetBuffer(updateKernel, "chunkOffsets", pathSmootherSystem.chunkOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frames", pathSmootherSystem.smoothFrames.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frameOffsets", pathSmootherSystem.smoothFrameOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frameCounts", pathSmootherSystem.smoothFrameCounts.computeBuffer);
ropeShader.SetBuffer(updateKernel, "sectionData", sectionData.computeBuffer);
ropeShader.SetBuffer(updateKernel, "sectionOffsets", sectionOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "sectionIndices", sectionIndices.computeBuffer);
ropeShader.SetBuffer(updateKernel, "vertexOffsets", vertexOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "triangleOffsets", triangleOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "triangleCounts", triangleCounts.computeBuffer);
ropeShader.SetBuffer(updateKernel, "extrudedData", rendererData.computeBuffer);
ropeShader.SetBuffer(updateKernel, "pathData", pathSmootherSystem.pathData.computeBuffer);
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
int threadGroups = ComputeMath.ThreadGroupCount(batch.rendererCount, 128);
ropeShader.SetInt("firstRenderer", batch.firstRenderer);
ropeShader.SetInt("rendererCount", batch.rendererCount);
ropeShader.SetBuffer(updateKernel, "vertices", batch.gpuVertexBuffer);
ropeShader.SetBuffer(updateKernel, "tris", batch.gpuIndexBuffer);
ropeShader.Dispatch(updateKernel, threadGroups, 1, 1);
var rp = batch.renderParams;
rp.worldBounds = m_Solver.bounds;
Graphics.RenderMesh(rp, batch.mesh, 0, m_Solver.transform.localToWorldMatrix, m_Solver.transform.localToWorldMatrix);
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f8977537c032b46c680d6b11b587e949
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
using UnityEngine;
using UnityEngine.Rendering;
using Unity.Profiling;
using System.Collections.Generic;
using Unity.Collections;
namespace Obi
{
public class ComputeLineRopeRenderSystem : ObiLineRopeRenderSystem
{
private ComputeShader ropeShader;
private int updateKernel;
public ComputeLineRopeRenderSystem(ObiSolver solver) : base(solver)
{
ropeShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/RopeLineRendering"));
updateKernel = ropeShader.FindKernel("UpdateLineMesh");
}
public override void Setup()
{
base.Setup();
// Initialize each batch:
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Initialize(layout, true);
vertexOffsets.AsComputeBuffer<int>();
triangleOffsets.AsComputeBuffer<int>();
triangleCounts.AsComputeBuffer<int>();
pathSmootherIndices.AsComputeBuffer<int>();
rendererData.AsComputeBuffer<BurstLineMeshData>();
pathSmootherSystem.chunkOffsets.AsComputeBuffer<int>();
}
public override void Render() { }
public override void RenderFromCamera(Camera camera)
{
using (m_RenderMarker.Auto())
{
if (pathSmootherSystem == null)
return;
// Single array: Cannot merge into a single vertices array, otherwise we would need to bring back to CPU for passing indices to each mesh.
// Individual meshes: Cannot do each renderer independently (like we do with cloth) since each rope is done sequentially, would not parallelize at all.
// Batches: 1 mesh per batch: best approach, but 1) bounds must be calculated per or solver, so we can only cull entire solver. Culling happens on the CPU, cannot bring back bounds from the CPU.
// Cloth and Softbodies are rendered manually, particles are too. So Ropes could too.
// In Burst, we need merge all cloth mesh data into array for parallel processing, without using one schedule() per mesh.
// So instead of writing slices of mesh data back to their original meshes, let's create one mesh per batch and draw it ourselves.
// Basically the same as with ropes.
if (pathSmootherSystem.chunkOffsets != null && pathSmootherSystem.chunkOffsets.count > 0)
{
ropeShader.SetBuffer(updateKernel, "pathSmootherIndices", pathSmootherIndices.computeBuffer);
ropeShader.SetBuffer(updateKernel, "chunkOffsets", pathSmootherSystem.chunkOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frames", pathSmootherSystem.smoothFrames.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frameOffsets", pathSmootherSystem.smoothFrameOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frameCounts", pathSmootherSystem.smoothFrameCounts.computeBuffer);
ropeShader.SetBuffer(updateKernel, "vertexOffsets", vertexOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "triangleOffsets", triangleOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "triangleCounts", triangleCounts.computeBuffer);
ropeShader.SetBuffer(updateKernel, "rendererData", rendererData.computeBuffer);
ropeShader.SetBuffer(updateKernel, "pathData", pathSmootherSystem.pathData.computeBuffer);
ropeShader.SetVector("localSpaceCamera", m_Solver.transform.InverseTransformPoint(camera.transform.position));
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
int threadGroups = ComputeMath.ThreadGroupCount(batch.rendererCount, 128);
ropeShader.SetInt("firstRenderer", batch.firstRenderer);
ropeShader.SetInt("rendererCount", batch.rendererCount);
ropeShader.SetBuffer(updateKernel, "vertices", batch.gpuVertexBuffer);
ropeShader.SetBuffer(updateKernel, "tris", batch.gpuIndexBuffer);
ropeShader.Dispatch(updateKernel, threadGroups, 1, 1);
var rp = batch.renderParams;
rp.worldBounds = m_Solver.bounds;
rp.camera = camera;
Graphics.RenderMesh(rp, batch.mesh, 0, m_Solver.transform.localToWorldMatrix, m_Solver.transform.localToWorldMatrix);
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1de4576d2ba2b4966af730ac7a09e224
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,108 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace Obi
{
public class ComputeMeshRopeRenderSystem : ObiMeshRopeRenderSystem
{
private ComputeShader ropeShader;
private int updateKernel;
public ComputeMeshRopeRenderSystem(ObiSolver solver) : base(solver)
{
ropeShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/RopeMeshRendering"));
updateKernel = ropeShader.FindKernel("UpdateRopeMesh");
}
protected override void CloseBatches()
{
// Initialize each batch:
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Initialize(sortedRenderers, meshData, meshIndices, layout, true);
meshData.PrepareForCompute();
meshIndices.AsComputeBuffer<int>();
sortedIndices.AsComputeBuffer<int>();
sortedOffsets.AsComputeBuffer<int>();
vertexOffsets.AsComputeBuffer<int>();
pathSmootherIndices.AsComputeBuffer<int>();
rendererData.AsComputeBuffer<BurstMeshData>();
pathSmootherSystem.chunkOffsets.AsComputeBuffer<int>();
base.CloseBatches();
}
public override void Render()
{
using (m_RenderMarker.Auto())
{
if (pathSmootherSystem == null)
return;
// Single array: Cannot merge into a single vertices array, otherwise we would need to bring back to CPU for passing indices to each mesh.
// Individual meshes: Cannot do each renderer independently (like we do with cloth) since each rope is done sequentially, would not parallelize at all.
// Batches: 1 mesh per batch: best approach, but 1) bounds must be calculated per or solver, so we can only cull entire solver. Culling happens on the CPU, cannot bring back bounds from the CPU.
// Cloth and Softbodies are rendered manually, particles are too. So Ropes could too.
// In Burst, we need merge all cloth mesh data into array for parallel processing, without using one schedule() per mesh.
// So instead of writing slices of mesh data back to their original meshes, let's create one mesh per batch and draw it ourselves.
// Basically the same as with ropes.
if (pathSmootherSystem.chunkOffsets != null && pathSmootherSystem.chunkOffsets.count > 0)
{
ropeShader.SetBuffer(updateKernel, "chunkOffsets", pathSmootherSystem.chunkOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "pathSmootherIndices", pathSmootherIndices.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frames", pathSmootherSystem.smoothFrames.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frameOffsets", pathSmootherSystem.smoothFrameOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "frameCounts", pathSmootherSystem.smoothFrameCounts.computeBuffer);
ropeShader.SetBuffer(updateKernel, "vertexOffsets", vertexOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "meshIndices", meshIndices.computeBuffer);
ropeShader.SetBuffer(updateKernel, "meshData", meshData.meshData.computeBuffer);
ropeShader.SetBuffer(updateKernel, "rendererData", rendererData.computeBuffer);
ropeShader.SetBuffer(updateKernel, "pathData", pathSmootherSystem.pathData.computeBuffer);
ropeShader.SetBuffer(updateKernel, "sortedIndices", sortedIndices.computeBuffer);
ropeShader.SetBuffer(updateKernel, "sortedOffsets", sortedOffsets.computeBuffer);
ropeShader.SetBuffer(updateKernel, "positions", meshData.restPositions.computeBuffer);
ropeShader.SetBuffer(updateKernel, "normals", meshData.restNormals.computeBuffer);
ropeShader.SetBuffer(updateKernel, "tangents", meshData.restTangents.computeBuffer);
ropeShader.SetBuffer(updateKernel, "colors", meshData.restColors.computeBuffer);
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
int threadGroups = ComputeMath.ThreadGroupCount(batch.rendererCount, 16);
ropeShader.SetInt("firstRenderer", batch.firstRenderer);
ropeShader.SetInt("rendererCount", batch.rendererCount);
ropeShader.SetBuffer(updateKernel, "vertices", batch.gpuVertexBuffer);
ropeShader.Dispatch(updateKernel, threadGroups, 1, 1);
var rp = batch.renderParams;
rp.worldBounds = m_Solver.bounds;
for (int m = 0; m < batch.materials.Length; ++m)
{
rp.material = batch.materials[m];
Graphics.RenderMesh(rp, batch.mesh, m, m_Solver.transform.localToWorldMatrix, m_Solver.transform.localToWorldMatrix);
}
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f880620ed267d4cb4a701183bcadfe15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,94 @@
using UnityEngine;
namespace Obi
{
public class ComputePathSmootherRenderSystem : ObiPathSmootherRenderSystem
{
private ComputeShader pathShader;
private int parallelTransportKernel;
private int decimateKernel;
private int smoothKernel;
public ComputePathSmootherRenderSystem(ObiSolver solver) : base(solver)
{
pathShader = GameObject.Instantiate(Resources.Load<ComputeShader>("Compute/PathSmoothing"));
parallelTransportKernel = pathShader.FindKernel("ParallelTransport");
decimateKernel = pathShader.FindKernel("Decimate");
smoothKernel = pathShader.FindKernel("ChaikinSmooth");
}
public override void Setup()
{
base.Setup();
particleIndices.AsComputeBuffer<int>();
rawFrameOffsets.AsComputeBuffer<int>();
pathData.AsComputeBuffer<BurstPathSmootherData>();
rawFrames.AsComputeBuffer<ObiPathFrame>();
decimatedFrameCounts.AsComputeBuffer<int>();
smoothFrames.AsComputeBuffer<ObiPathFrame>();
smoothFrameOffsets.AsComputeBuffer<int>();
smoothFrameCounts.AsComputeBuffer<int>();
}
public override void Render()
{
using (m_RenderMarker.Auto())
{
//base.Render();
var computeSolver = m_Solver.implementation as ComputeSolverImpl;
if (computeSolver.renderablePositionsBuffer != null && computeSolver.renderablePositionsBuffer.count > 0)
{
// wait for gpu data to be transferred:
pathData.WaitForReadback();
smoothFrames.WaitForReadback();
// update rest lenghts and upload to gpu:
base.Render();
pathData.Upload();
int threadGroups = ComputeMath.ThreadGroupCount(rawFrameOffsets.count, 128);
pathShader.SetInt("chunkCount", rawFrameOffsets.count);
pathShader.SetBuffer(parallelTransportKernel, "frameOffsets", rawFrameOffsets.computeBuffer);
pathShader.SetBuffer(parallelTransportKernel, "particleIndices", particleIndices.computeBuffer);
pathShader.SetBuffer(parallelTransportKernel, "renderablePositions", computeSolver.renderablePositionsBuffer);
pathShader.SetBuffer(parallelTransportKernel, "renderableOrientations", computeSolver.renderableOrientationsBuffer);
pathShader.SetBuffer(parallelTransportKernel, "principalRadii", computeSolver.principalRadiiBuffer);
pathShader.SetBuffer(parallelTransportKernel, "colors", computeSolver.colorsBuffer);
pathShader.SetBuffer(parallelTransportKernel, "pathData", pathData.computeBuffer);
pathShader.SetBuffer(parallelTransportKernel, "pathFrames", rawFrames.computeBuffer);
pathShader.Dispatch(parallelTransportKernel, threadGroups, 1, 1);
pathShader.SetBuffer(decimateKernel, "pathFrames", rawFrames.computeBuffer);
pathShader.SetBuffer(decimateKernel, "frameOffsets", rawFrameOffsets.computeBuffer);
pathShader.SetBuffer(decimateKernel, "decimatedFrameCounts", decimatedFrameCounts.computeBuffer);
pathShader.SetBuffer(decimateKernel, "pathData", pathData.computeBuffer);
pathShader.Dispatch(decimateKernel, threadGroups, 1, 1);
pathShader.SetBuffer(smoothKernel, "pathFrames", rawFrames.computeBuffer);
pathShader.SetBuffer(smoothKernel, "frameOffsets", rawFrameOffsets.computeBuffer);
pathShader.SetBuffer(smoothKernel, "decimatedFrameCounts", decimatedFrameCounts.computeBuffer);
pathShader.SetBuffer(smoothKernel, "smoothFrames", smoothFrames.computeBuffer);
pathShader.SetBuffer(smoothKernel, "smoothFrameOffsets", smoothFrameOffsets.computeBuffer);
pathShader.SetBuffer(smoothKernel, "smoothFrameCounts", smoothFrameCounts.computeBuffer);
pathShader.SetBuffer(smoothKernel, "pathData", pathData.computeBuffer);
pathShader.Dispatch(smoothKernel, threadGroups, 1, 1);
pathData.Readback();
smoothFrames.Readback();
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ed459657fb054e7b8e0c806e8e5016e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: