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());
        }
Esempio n. 4
0
        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());
        }
Esempio n. 5
0
        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;
        }
Esempio n. 7
0
        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());
        }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 10
0
        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);
                }
                    );
            }
        }
Esempio n. 11
0
 public DefaultSkinningAdapter(SkinningBlend method, RenderChunk chunk, Transform[] bones, Material material)
 {
 }