public void LoadAdaptor(SkinningCompute compute, SkinningBlend blend, bool tension) { switch (compute) { case SkinningCompute.Auto: if (SystemInfo.supportsComputeShaders) { LoadAdaptor(SkinningCompute.ForceGPGPU, blend, tension); } else { LoadAdaptor(SkinningCompute.ForceCPU, blend, tension); } break; case SkinningCompute.ForceGPGPU: { ComputeShaderSkinningAdapter computeAdapter = new ComputeShaderSkinningAdapter(blend, computeShader, chunk, chunk.GetBones(transform.parent), material, tension); adapter = computeAdapter as IRenderAdapter; disposable = computeAdapter as IDisposable; } break; case SkinningCompute.ForceCPU: { DefaultSkinningAdapter defaultAdapter = new DefaultSkinningAdapter(blend, chunk, chunk.GetBones(transform.parent), material); adapter = defaultAdapter as IRenderAdapter; disposable = defaultAdapter as IDisposable; } break; } }
public void ReloadAdaptor(SkinningCompute compute, SkinningBlend blend, bool tension) { if (disposable != null) { disposable.Dispose(); } adapter = null; disposable = null; LoadAdaptor(compute, blend, tension); }
public static ICompute CreateComputeBy(SkinningBlend method, RenderChunk chunk) { switch (method) { case SkinningBlend.Linear: return(new LinearBlendSkinningCompute()); case SkinningBlend.DualQuaternion: return(new DualQuaternionBlendSkinningCompute()); default: return(null); } }
public static IDisposableDispatch CreateComputeBy(SkinningBlend method, ComputeShader computeShader, RenderChunk chunk, Transform[] bones, Func <ComputeBuffer> getPerVertexBuffer, Func <ComputeBuffer> getPerVertexSkinBuffer, Func <ComputeBuffer> getPerVertexStream) { switch (method) { case SkinningBlend.Linear: return(new LinearBlendSkinningDispatcher(computeShader, chunk, bones, getPerVertexBuffer, getPerVertexSkinBuffer, getPerVertexStream)); case SkinningBlend.DualQuaternion: return(new DualQuaternionBlendSkinningDispatcher(computeShader, chunk, bones, getPerVertexBuffer, getPerVertexSkinBuffer, getPerVertexStream)); case SkinningBlend.OptimizedCenterOfRotation: return(new OptimizedCenterOfRotationSkinningDispatcher(computeShader, chunk, bones, getPerVertexBuffer, getPerVertexSkinBuffer, getPerVertexStream)); default: return(null); } }
public ComputeShaderSkinningAdapter(SkinningBlend method, ComputeShader computeShader, RenderChunk chunk, Transform[] bones, Material material, bool tension = false) { this.method = method; perVertexBuffer = new ComputeBuffer(chunk.vertexCount, Marshal.SizeOf(typeof(DataPerVertex))); perVertexBuffer.SetData(chunk.dataPerVertex); perVertexSkinBuffer = new ComputeBuffer(chunk.vertexCount, Marshal.SizeOf(typeof(SkinPerVertex))); perVertexSkinBuffer.SetData(chunk.skinPerVertex); perVertexStream = new ComputeBuffer(chunk.vertexCount, Marshal.SizeOf(typeof(DataPerVertex))); perVertexStream.SetData(chunk.dataPerVertex); indexBuffer = new ComputeBuffer(chunk.indices.Length, sizeof(int)); indexBuffer.SetData(chunk.indices); indexCountBuffer = new ComputeBuffer(chunk.indexCounts.Length, sizeof(int)); indexCountBuffer.SetData(chunk.indexCounts); sourceDispatcher = new DataToDataDispatcher( computeShader, () => perVertexBuffer, () => perVertexStream ); dispatchcer = DispatcherFactory.CreateComputeBy( method, computeShader, chunk, bones, () => perVertexBuffer, () => perVertexSkinBuffer, () => perVertexStream ); if (!tension) { renderer = new ComputeShaderRenderer( chunk, material, () => perVertexStream, () => indexBuffer, () => indexCountBuffer ); } else { edgeLengthBuffer = new ComputeBuffer(chunk.edges.Length, sizeof(float)); edgeLengthBuffer.SetData(chunk.edges); tensionBuffer = new ComputeBuffer(chunk.vertexCount, sizeof(float)); tensionBuffer.SetData(new float[chunk.vertexCount]); tensionDispatcher = new TensionDispatcher( computeShader, chunk, () => perVertexStream, () => indexBuffer, () => edgeLengthBuffer, () => tensionBuffer ); renderer = new TensionRenderer(chunk, material, () => tensionBuffer, () => perVertexStream, () => indexBuffer, () => indexCountBuffer); } }
public ComputeShaderSkinningAdapter(SkinningBlend method, ComputeShader computeShader, RenderChunk chunk, Transform[] bones, Material material, bool tension = false) { this.method = method; perVertexBuffer = new ComputeBuffer(chunk.vertexCount, Marshal.SizeOf(typeof(DataPerVertex))); perVertexBuffer.SetData(chunk.dataPerVertex); perVertexSkinBuffer = new ComputeBuffer(chunk.vertexCount, Marshal.SizeOf(typeof(SkinPerVertex))); perVertexSkinBuffer.SetData(chunk.skinPerVertex); perVertexStream = new ComputeBuffer(chunk.vertexCount, Marshal.SizeOf(typeof(DataPerVertex))); perVertexStream.SetData(chunk.dataPerVertex); indexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, chunk.indices.Length, sizeof(int)); indexBuffer.SetData(chunk.indices); indexCountBuffer = new ComputeBuffer(chunk.indexCounts.Length, sizeof(int)); indexCountBuffer.SetData(chunk.indexCounts); minmaxBoundsBuffer = new ComputeBuffer(1, Marshal.SizeOf <Vector3>() * 2, ComputeBufferType.Structured); sourceDispatcher = new DataToDataDispatcher( computeShader, () => perVertexBuffer, () => perVertexStream, () => minmaxBoundsBuffer ); dispatchcer = DispatcherFactory.CreateComputeBy( method, computeShader, chunk, bones, () => perVertexBuffer, () => perVertexSkinBuffer, () => perVertexStream, () => minmaxBoundsBuffer ); if (!tension) { renderer = new ComputeShaderRenderer( chunk, material, () => perVertexStream, () => indexBuffer, () => { Bounds b = new Bounds(); // TODO:: REMOVE GC ALLOCATION, fixed or stack allocation as c# Array Vector3[] p = new Vector3[2]; minmaxBoundsBuffer.GetData(p); b.center = (p[0] + p[1]) / 2.0f; b.extents = (p[1] - p[0]) / 2.0f; return(b); } ); } else { edgeLengthBuffer = new ComputeBuffer(chunk.edges.Length, sizeof(float)); edgeLengthBuffer.SetData(chunk.edges); tensionBuffer = new ComputeBuffer(chunk.vertexCount, sizeof(float)); tensionBuffer.SetData(new float[chunk.vertexCount]); tensionDispatcher = new TensionDispatcher( computeShader, chunk, () => perVertexStream, () => indexBuffer, () => edgeLengthBuffer, () => tensionBuffer ); renderer = new TensionRenderer( chunk, material, () => tensionBuffer, () => perVertexStream, () => indexBuffer, () => { Bounds b = new Bounds(); // TODO:: REMOVE GC ALLOCATION, fixed or stack allocation as c# Array Vector3[] p = new Vector3[2]; minmaxBoundsBuffer.GetData(p); b.center = (p[0] + p[1]) / 2.0f; b.extents = (p[1] - p[0]) / 2.0f; return(b); } ); } }
public DefaultSkinningAdapter(SkinningBlend method, RenderChunk chunk, Transform[] bones, Material material) { }