public DualQuaternionBlendSkinningDispatcher(ComputeShader computeShader, RenderChunk chunk, Transform[] bones, Func <ComputeBuffer> getPerVertexBuffer, Func <ComputeBuffer> getPerVertexSkinBuffer, Func <ComputeBuffer> getPerVertexStream) { this.computeShader = computeShader; kernelIndex = computeShader.FindKernel("DualQuaternionBlendCompute"); computeShader.GetKernelThreadGroupSizes(kernelIndex, out maxThreadSizeX, out maxThreadSizeY, out maxThreadSizeZ); vertexCount = chunk.vertexCount; this.bones = bones; currentPoseDQArray = new DualQuaternion[bones.Length]; boneRestPoseDQBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(DualQuaternion))); boneCurrentPoseDQBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(DualQuaternion))); boneRestPoseDQBuffer.SetData(chunk.inverseRestPoseDQArray); computeShader.SetInt("vertexCount", vertexCount); computeShader.SetBuffer(kernelIndex, "currPoseDQ", boneCurrentPoseDQBuffer); computeShader.SetBuffer(kernelIndex, "restPoseDQ", boneRestPoseDQBuffer); computeShader.SetBuffer(kernelIndex, "vertices", getPerVertexBuffer()); computeShader.SetBuffer(kernelIndex, "skin", getPerVertexSkinBuffer()); computeShader.SetBuffer(kernelIndex, "output", getPerVertexStream()); }
public LinearBlendSkinningDispatcher(ComputeShader computeShader, RenderChunk chunk, Transform[] bones, Func <ComputeBuffer> getPerVertexBuffer, Func <ComputeBuffer> getPerVertexSkinBuffer, Func <ComputeBuffer> getPerVertexStream) { this.computeShader = computeShader; kernelIndex = computeShader.FindKernel("LinearBlendCompute"); computeShader.GetKernelThreadGroupSizes(kernelIndex, out maxThreadSizeX, out maxThreadSizeY, out maxThreadSizeZ); vertexCount = chunk.vertexCount; this.bones = bones; currentPoseMatrixArray = new Matrix4x4[bones.Length]; boneRestPoseMatrixBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(Matrix4x4))); boneRestPoseMatrixBuffer.SetData(chunk.inverseRestPoseMatrixArray); boneCurrentPoseMatrixBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(Matrix4x4))); for (int i = 0; i < currentPoseMatrixArray.Length; i++) { currentPoseMatrixArray[i] = bones[i].localToWorldMatrix; } boneCurrentPoseMatrixBuffer.SetData(currentPoseMatrixArray); computeShader.SetInt("vertexCount", vertexCount); computeShader.SetBuffer(kernelIndex, "currPoseMtrx", boneCurrentPoseMatrixBuffer); computeShader.SetBuffer(kernelIndex, "restPoseMtrx", boneRestPoseMatrixBuffer); computeShader.SetBuffer(kernelIndex, "vertices", getPerVertexBuffer()); computeShader.SetBuffer(kernelIndex, "skin", getPerVertexSkinBuffer()); computeShader.SetBuffer(kernelIndex, "output", getPerVertexStream()); }
public ComputeShaderRenderer(RenderChunk chunk, Material material, Func <ComputeBuffer> getPerVertexStream, Func <ComputeBuffer> getIndexBuffer, Func <ComputeBuffer> getIndexCountBuffer) { this.material = material; this.getIndexBuffer = getIndexBuffer; this.getIndexCountBuffer = getIndexCountBuffer; this.getPerVertexStream = getPerVertexStream; material.SetBuffer("triangles", getIndexBuffer()); material.SetBuffer("triCountPerTextureIndex", getIndexCountBuffer()); material.SetBuffer("dataPerVertex", getPerVertexStream()); }
public ComputeShaderRenderer( RenderChunk chunk, Material material, Func <ComputeBuffer> getPerVertexStream, Func <GraphicsBuffer> getIndexBuffer, Func <Bounds> getBounds ) { this.material = material; this.getIndexBuffer = getIndexBuffer; this.getPerVertexStream = getPerVertexStream; this.getBounds = getBounds; material.SetBuffer("dataPerVertex", getPerVertexStream()); }
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 TensionDispatcher(ComputeShader computeShader, RenderChunk chunk, Func <ComputeBuffer> getPerVertexStream, Func <ComputeBuffer> getIndexBuffer, Func <ComputeBuffer> getEdgeLengthBuffer, Func <ComputeBuffer> getTensionPerVertex) { this.computeShader = computeShader; kernelIndex = computeShader.FindKernel("TensionCompute"); uint maxThreadSizeY, maxThreadSizeZ; computeShader.GetKernelThreadGroupSizes(kernelIndex, out maxThreadSizeX, out maxThreadSizeY, out maxThreadSizeZ); this.getPerVertexStream = getPerVertexStream; this.getIndexBuffer = getIndexBuffer; this.getEdgeLengthBuffer = getEdgeLengthBuffer; this.getTensionPerVertex = getTensionPerVertex; patchCount = chunk.indices.Length / chunk.topologyCount; }
public OptimizedCenterOfRotationSkinningDispatcher( ComputeShader computeShader, RenderChunk chunk, Transform[] bones, Func <ComputeBuffer> getPerVertexBuffer, Func <ComputeBuffer> getPerVertexSkinBuffer, Func <ComputeBuffer> getPerVertexStream, Func <ComputeBuffer> getMinMaxBoundsBuffer ) { uint maxThreadSizeY, maxThreadSizeZ; this.computeShader = computeShader; kernelIndex = computeShader.FindKernel("OptimizedCenterOfRotationCompute"); computeShader.GetKernelThreadGroupSizes(kernelIndex, out maxThreadSizeX, out maxThreadSizeY, out maxThreadSizeZ); vertexCount = chunk.vertexCount; this.bones = bones; currentPoseMatrixArray = new Matrix4x4[bones.Length]; currentPoseRotationQuatArray = new Quaternion[bones.Length]; boneRestPoseMatrixBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(Matrix4x4))); boneCurrentPoseMatrixBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(Matrix4x4))); boneRestPoseRotationQuatBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(Quaternion))); boneCurrentPoseRotationQuatBuffer = new ComputeBuffer(bones.Length, Marshal.SizeOf(typeof(Quaternion))); vertexCenterOfRotationBuffer = new ComputeBuffer(chunk.vertexCount, Marshal.SizeOf(typeof(Vector3))); boneRestPoseMatrixBuffer.SetData(chunk.inverseRestPoseMatrixArray); boneRestPoseRotationQuatBuffer.SetData(chunk.inverseRestPoseRotationArray); vertexCenterOfRotationBuffer.SetData(chunk.centerOfRotationPositionArray); computeShader.SetInt("vertexCount", vertexCount); computeShader.SetBuffer(kernelIndex, "currPoseMtrx", boneCurrentPoseMatrixBuffer); computeShader.SetBuffer(kernelIndex, "restPoseMtrx", boneRestPoseMatrixBuffer); computeShader.SetBuffer(kernelIndex, "currPoseRot", boneCurrentPoseRotationQuatBuffer); computeShader.SetBuffer(kernelIndex, "restPoseRot", boneRestPoseRotationQuatBuffer); computeShader.SetBuffer(kernelIndex, "CORBuffer", vertexCenterOfRotationBuffer); computeShader.SetBuffer(kernelIndex, "vertices", getPerVertexBuffer()); computeShader.SetBuffer(kernelIndex, "skin", getPerVertexSkinBuffer()); computeShader.SetBuffer(kernelIndex, "output", getPerVertexStream()); computeShader.SetBuffer(kernelIndex, "minmax", getMinMaxBoundsBuffer()); }
public static IDisposableDispatch CreateComputeBy( SkinningBlend method, ComputeShader computeShader, RenderChunk chunk, Transform[] bones, Func <ComputeBuffer> getPerVertexBuffer, Func <ComputeBuffer> getPerVertexSkinBuffer, Func <ComputeBuffer> getPerVertexStream, Func <ComputeBuffer> getMinMaxBoundsBuffer ) { switch (method) { case SkinningBlend.Linear: return(new LinearBlendSkinningDispatcher(computeShader, chunk, bones, getPerVertexBuffer, getPerVertexSkinBuffer, getPerVertexStream, getMinMaxBoundsBuffer)); case SkinningBlend.DualQuaternion: return(new DualQuaternionBlendSkinningDispatcher(computeShader, chunk, bones, getPerVertexBuffer, getPerVertexSkinBuffer, getPerVertexStream, getMinMaxBoundsBuffer)); case SkinningBlend.OptimizedCenterOfRotation: return(new OptimizedCenterOfRotationSkinningDispatcher(computeShader, chunk, bones, getPerVertexBuffer, getPerVertexSkinBuffer, getPerVertexStream, getMinMaxBoundsBuffer)); 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) { }