コード例 #1
0
        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;
            }
        }
コード例 #2
0
        public void ReloadAdaptor(SkinningCompute compute, SkinningBlend blend, bool tension)
        {
            if (disposable != null)
            {
                disposable.Dispose();
            }

            adapter    = null;
            disposable = null;

            LoadAdaptor(compute, blend, tension);
        }
コード例 #3
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);
            }
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
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 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);
            }
        }
コード例 #6
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);
                }
                    );
            }
        }
コード例 #7
0
 public DefaultSkinningAdapter(SkinningBlend method, RenderChunk chunk, Transform[] bones, Material material)
 {
 }