示例#1
0
        private bool GetComputeBufferData()
        {
            _HeightmapBuffer?.GetData(_Heightmap);
            _CaveNoiseBuffer?.GetData(_CaveNoise);

            _HeightmapBuffer?.Release();
            _CaveNoiseBuffer?.Release();

            return(true);
        }
示例#2
0
        private void OnGUI()
        {
            if (!terrainEdit)
            {
                terrainEdit = Resources.Load <ComputeShader>("TerrainEdit");
            }
            terrainData = (MTerrainData)EditorGUILayout.ObjectField("Terrain Data", terrainData, typeof(MTerrainData), false);
            if (!terrainData)
            {
                return;
            }
            chunkPosition    = EditorGUILayout.Vector2IntField("Chunk Position", new Vector2Int(chunkPosition.x, chunkPosition.y));
            heightTexture    = EditorGUILayout.ObjectField("Height Texture", heightTexture, typeof(Texture), false) as Texture;
            targetChunkCount = EditorGUILayout.IntField("Chunk Count", targetChunkCount);
            targetChunkCount = max(0, targetChunkCount);

            int largestChunkCount = (int)(pow(2.0, terrainData.GetLodOffset()) + 0.1);

            if (GUILayout.Button("Update Height Texture"))
            {
                VirtualTextureLoader loader = new VirtualTextureLoader(
                    terrainData.heightmapPath,
                    terrainEdit,
                    largestChunkCount,
                    MTerrain.MASK_RESOLUTION, true, null);
                RenderTexture cacheRt = new RenderTexture(new RenderTextureDescriptor
                {
                    width             = MTerrain.MASK_RESOLUTION,
                    height            = MTerrain.MASK_RESOLUTION,
                    volumeDepth       = 1,
                    dimension         = UnityEngine.Rendering.TextureDimension.Tex2DArray,
                    msaaSamples       = 1,
                    graphicsFormat    = UnityEngine.Experimental.Rendering.GraphicsFormat.R32_SFloat,
                    enableRandomWrite = true
                });
                cacheRt.Create();
                int           mipLevel       = 0;
                int           meshResolution = terrainData.GetMeshResolution();
                int           saveMipLevel   = 0;
                ComputeBuffer cb             = new ComputeBuffer(meshResolution * meshResolution, sizeof(float2));

                float2[]      resultArr = new float2[meshResolution * meshResolution];
                RenderTexture mipRT     = new RenderTexture(MTerrain.MASK_RESOLUTION, MTerrain.MASK_RESOLUTION, 0, UnityEngine.Experimental.Rendering.GraphicsFormat.R32G32_SFloat, mipLevel);
                mipRT.enableRandomWrite = true;
                mipRT.useMipMap         = true;
                mipRT.autoGenerateMips  = false;
                mipRT.Create();
                System.IO.FileStream fsm = new System.IO.FileStream(terrainData.boundPath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);
                for (int i = MTerrain.MASK_RESOLUTION; i > 0; i /= 2)
                {
                    mipLevel++;
                    if (i <= meshResolution)
                    {
                        saveMipLevel++;
                    }
                }
                MTerrainBoundingTree btree = new MTerrainBoundingTree(saveMipLevel);
                for (int x = 0; x < targetChunkCount; ++x)
                {
                    for (int y = 0; y < targetChunkCount; ++y)
                    {
                        int2 pos = int2(x, y) + int2(chunkPosition.x, chunkPosition.y);
                        if (pos.x >= largestChunkCount || pos.y >= largestChunkCount)
                        {
                            continue;
                        }
                        terrainEdit.SetTexture(6, ShaderIDs._SourceTex, heightTexture);
                        terrainEdit.SetTexture(6, ShaderIDs._DestTex, cacheRt);
                        terrainEdit.SetInt(ShaderIDs._Count, MTerrain.MASK_RESOLUTION);
                        terrainEdit.SetInt(ShaderIDs._OffsetIndex, 0);
                        terrainEdit.SetVector("_ScaleOffset", float4(float2(1.0 / targetChunkCount), float2(x, y) / targetChunkCount));
                        const int disp = MTerrain.MASK_RESOLUTION / 16;
                        terrainEdit.Dispatch(6, disp, disp, 1);
                        loader.WriteToDisk(cacheRt, 0, pos);
                        for (int i = 0, res = MTerrain.MASK_RESOLUTION; i < mipLevel; ++i, res /= 2)
                        {
                            int pass;
                            if (i == 0)
                            {
                                pass = 7;
                                terrainEdit.SetTexture(pass, "_SourceArray", cacheRt);
                                terrainEdit.SetTexture(pass, "_Mip1", mipRT);
                            }
                            else
                            {
                                if (res <= meshResolution)
                                {
                                    pass = 9;
                                    terrainEdit.SetBuffer(pass, "_DataBuffer", cb);
                                }
                                else
                                {
                                    pass = 8;
                                }
                                terrainEdit.SetTexture(pass, "_Mip0", mipRT, i - 1);
                                terrainEdit.SetTexture(pass, "_Mip1", mipRT, i);
                            }
                            terrainEdit.SetInt(ShaderIDs._Count, res);
                            int mipdisp = Mathf.CeilToInt(res / 16f);
                            terrainEdit.Dispatch(pass, mipdisp, mipdisp, 1);
                            if (pass == 9)
                            {
                                cb.GetData(resultArr, 0, 0, res * res);
                                int targetMipLevel = mipLevel - 1 - i;
                                for (int xx = 0; xx < res * res; ++xx)
                                {
                                    btree[xx, targetMipLevel] = resultArr[xx];
                                }
                            }
                        }
                        btree.WriteToDisk(fsm, x + y * largestChunkCount);
                    }
                }

                btree.Dispose();
                cacheRt.Release();
                cb.Dispose();
                mipRT.Release();
                loader.Dispose();
                fsm.Dispose();
                Debug.Log("Finish!");
            }
            maskTexture = EditorGUILayout.ObjectField("Mask Texture", maskTexture, typeof(Texture), false) as Texture;
            void SaveToMask(RenderTexture cacheRt)
            {
                VirtualTextureLoader loader = new VirtualTextureLoader(
                    terrainData.maskmapPath,
                    terrainEdit,
                    largestChunkCount,
                    MTerrain.MASK_RESOLUTION, false, null);

                for (int x = 0; x < targetChunkCount; ++x)
                {
                    for (int y = 0; y < targetChunkCount; ++y)
                    {
                        int2 pos = int2(x, y) + int2(chunkPosition.x, chunkPosition.y);
                        if (pos.x >= largestChunkCount || pos.y >= largestChunkCount)
                        {
                            continue;
                        }
                        terrainEdit.SetTexture(6, ShaderIDs._SourceTex, maskTexture);
                        terrainEdit.SetTexture(6, ShaderIDs._DestTex, cacheRt);
                        terrainEdit.SetInt(ShaderIDs._Count, MTerrain.MASK_RESOLUTION);
                        terrainEdit.SetInt(ShaderIDs._OffsetIndex, 0);
                        terrainEdit.SetVector("_ScaleOffset", float4(float2(1.0 / targetChunkCount), float2(x, y) / targetChunkCount));
                        const int disp = MTerrain.MASK_RESOLUTION / 16;
                        terrainEdit.Dispatch(6, disp, disp, 1);
                        loader.WriteToDisk(cacheRt, 0, pos);
                    }
                }
                loader.Dispose();
            }

            if (GUILayout.Button("Update Mask Texture"))
            {
                RenderTexture cacheRt = new RenderTexture(new RenderTextureDescriptor
                {
                    width             = MTerrain.MASK_RESOLUTION,
                    height            = MTerrain.MASK_RESOLUTION,
                    volumeDepth       = 1,
                    dimension         = UnityEngine.Rendering.TextureDimension.Tex2DArray,
                    msaaSamples       = 1,
                    graphicsFormat    = UnityEngine.Experimental.Rendering.GraphicsFormat.R32_SFloat,
                    enableRandomWrite = true
                });
                cacheRt.Create();
                SaveToMask(cacheRt);
                cacheRt.Release();
            }
        }
    private void SolveBoundaries(ComputeBuffer vBuffer, ComputeBuffer pBuffer, ComputeBuffer dBuffer)
    {
        vBuffer.GetData(velocityFieldBuffer);
        pBuffer.GetData(pressureFieldBuffer);
        if (dBuffer != null)
        {
            dBuffer.GetData(dyeFieldBuffer);
        }

        for (uint i = 0; i < particleWidth; ++i)
        {
            for (uint j = 0; j < particleWidth; ++j)
            {
                uint id = i * particleWidth + j;

                if (i == 0)
                {
                    // bottom
                    velocityFieldBuffer[id] = -velocityFieldBuffer[(i + 1) * particleWidth + (j + 1)];
                    pressureFieldBuffer[id] = pressureFieldBuffer[(i + 1) * particleWidth + (j)];
                    if (dBuffer != null)
                    {
                        dyeFieldBuffer[id] = 0.0f;
                    }
                }
                else if (i == particleWidth - 1)
                {
                    // top
                    velocityFieldBuffer[id] = -velocityFieldBuffer[(i - 1) * particleWidth + (j)];
                    pressureFieldBuffer[id] = pressureFieldBuffer[(i - 1) * particleWidth + (j)];
                    if (dBuffer != null)
                    {
                        dyeFieldBuffer[id] = 0.0f;
                    }
                }
                else if (j == 0)
                {
                    // left
                    velocityFieldBuffer[id] = -velocityFieldBuffer[(i) * particleWidth + (j + 1)];
                    pressureFieldBuffer[id] = pressureFieldBuffer[(i) * particleWidth + (j + 1)];
                    if (dBuffer != null)
                    {
                        dyeFieldBuffer[id] = 0.0f;
                    }
                }
                else if (j == particleWidth - 1)
                {
                    // right
                    velocityFieldBuffer[id] = -velocityFieldBuffer[(i) * particleWidth + (j - 1)];
                    pressureFieldBuffer[id] = pressureFieldBuffer[(i) * particleWidth + (j - 1)];
                    if (dBuffer != null)
                    {
                        dyeFieldBuffer[id] = 0.0f;
                    }
                }
            }
        }

        vBuffer.SetData(velocityFieldBuffer);
        pBuffer.SetData(pressureFieldBuffer);
        if (dBuffer != null)
        {
            dBuffer.SetData(dyeFieldBuffer);
        }
    }
示例#4
0
        protected override void Compute()
        {
            const string method = nameof(Compute);

            logger.Log(Logger.EventType.Method, $"{Context(method)}: started.");
            //SetStatusMessage($"Step 3/{(writeFactors ? 4 : 3)}: Computing absorption factors...");


            // initialize parameters in shader.
            stopwatch.Record(Category.Shader, SetShaderConstants);
            logger.Log(Logger.EventType.Step, $"{Context(method)}: Set shader parameters.");

            stopwatch.Start(Category.Shader);
            // get kernel handles.
            var handlePart1       = shader.FindKernel("get_dists_part1");
            var handlePart2       = shader.FindKernel("get_dists_part2");
            var handleAbsorptions = shader.FindKernel("get_absorptions");

            stopwatch.Stop(Category.Shader);
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Retrieved kernel handles.");

            // make buffers.
            stopwatch.Start(Category.Buffer);
            var outputBufferCellPart1   = new ComputeBuffer(coordinates.Length, sizeof(float) * 2);
            var outputBufferSamplePart1 = new ComputeBuffer(coordinates.Length, sizeof(float) * 2);
            var outputBufferCellPart2   = new ComputeBuffer(coordinates.Length, sizeof(float) * 2);
            var outputBufferSamplePart2 = new ComputeBuffer(coordinates.Length, sizeof(float) * 2);
            var absorptionsBuffer       = new ComputeBuffer(coordinates.Length, sizeof(float) * 3);

            logger.Log(Logger.EventType.Data, $"{Context(method)}: Created buffers.");

            // set buffers for part1 kernel.
            shader.SetBuffer(handlePart1, "coordinates", _inputBuffer);
            shader.SetBuffer(handlePart1, "distances_sample_part1", outputBufferSamplePart1);
            shader.SetBuffer(handlePart1, "distances_cell_part1", outputBufferCellPart1);
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Wrote data to buffers.");

            _inputBuffer.SetData(coordinates);

            stopwatch.Stop(Category.Buffer);

            // compute part1 distances.
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: part1 distances kernel dispatch.");
            stopwatch.Record(Category.Shader, () => shader.Dispatch(handlePart1, threadGroupsX, 1, 1));
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: part1 distances kernel return.");

            stopwatch.Record(Category.Buffer, () =>
            {
                // set buffers for part2 kernel.
                shader.SetBuffer(handlePart2, "coordinates", _inputBuffer);
                shader.SetBuffer(handlePart2, "distances_sample_part2", outputBufferSamplePart2);
                shader.SetBuffer(handlePart2, "distances_cell_part2", outputBufferCellPart2);

                // set shared buffers for absorption factor kernel.
                shader.SetBuffer(handleAbsorptions, "coordinates", _inputBuffer);
                shader.SetBuffer(handleAbsorptions, "distances_sample_part1", outputBufferSamplePart1);
                shader.SetBuffer(handleAbsorptions, "distances_cell_part1", outputBufferCellPart1);
                shader.SetBuffer(handleAbsorptions, "absorptions", absorptionsBuffer);
                shader.SetBuffer(handleAbsorptions, "indicator_mask", _maskBuffer);
            });

            var absorptionsTemp = new Vector3[coordinates.Length];

            Array.Clear(absorptionsTemp, 0, absorptionsTemp.Length);
            stopwatch.Record(Category.Buffer, () => absorptionsBuffer.SetData(absorptionsTemp));

            for (int j = 0; j < _nrAnglesTheta; j++)
            {
                // set rotation parameters.
                var j1 = j;
                stopwatch.Record(Category.Buffer, () =>
                                 shader.SetFloats("rot", (float)Math.Cos(Math.PI - GetThetaAt(j1)),
                                                  (float)Math.Sin(Math.PI - GetThetaAt(j1)))
                                 );

                // compute part2 distances.
                stopwatch.Record(Category.Shader, () => shader.Dispatch(handlePart2, threadGroupsX, 1, 1));

                // set iterative buffers for absorption factors kernel.
                stopwatch.Record(Category.Buffer, () =>
                {
                    shader.SetBuffer(handleAbsorptions, "distances_sample_part2", outputBufferSamplePart2);
                    shader.SetBuffer(handleAbsorptions, "distances_cell_part2", outputBufferCellPart2);
                });

                for (int i = 0; i < _nrAnglesAlpha; i++)
                {
                    var v             = GetDistanceVector(i, j);
                    var stretchFactor = GetStretchFactor(v);

                    stopwatch.Record(Category.Buffer, () => shader.SetFloat("stretch_factor", stretchFactor));
                    stopwatch.Record(Category.Shader, () => shader.Dispatch(handleAbsorptions, threadGroupsX, 1, 1));
                    stopwatch.Record(Category.Buffer, () => absorptionsBuffer.GetData(absorptionsTemp));

                    _absorptionFactors[i, j] = GetAbsorptionFactor(absorptionsTemp);
                }
            }
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Calculated all absorptions.");

            // release buffers.
            stopwatch.Record(Category.Buffer, () =>
            {
                _inputBuffer.Release();
                _maskBuffer.Release();
                outputBufferCellPart1.Release();
                outputBufferSamplePart1.Release();
                outputBufferCellPart2.Release();
                outputBufferSamplePart2.Release();
                absorptionsBuffer.Release();
            });
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Shader buffers released.");

            logger.Log(Logger.EventType.Method, $"{Context(method)}: done.");
        }
    public void Emulate(
        int stateCount,
        int spaceSize,
        int timeSize,
        int randSeed,
        Rule[] rules,
        bool inPlace
        )
    {
        Debug.Assert(rules[0].tablePackN == tablePackN);

        var packer          = rules[0].packer;
        var spaceSizePacked = packer.GetPackedSize(spaceSize);

        var timestepsPerCall = (timeSize - Rule.timeNeighbourhoodRadius);

        if (usePackedPacked)
        {
            var packedRule = new PackedSpace(
                new Packer(4 * 4),
                rules[0].tablePackedNCell.Length);
            ComputeShaderEx.EnsureBuffer(
                ref ruleTablePackedNCellBuffer,
                rules.Length * packedRule.packed.Length,
                sizeof(int));

            for (var i = 0; i < rules.Length; i++)
            {
                var rule = rules[i];
                for (var j = 0; j < rule.tablePackedNCell.Length; j++)
                {
                    packedRule[j] = rule.tablePackedNCell[j];
                }
                ruleTablePackedNCellBuffer.SetData(
                    packedRule.packed,
                    0,
                    i * packedRule.packed.Length,
                    packedRule.packed.Length);
            }
        }
        else
        {
            ComputeShaderEx.EnsureBuffer(
                ref ruleTablePackedNCellBuffer,
                rules.Length * rules[0].tablePackedNCell.Length,
                sizeof(int));

            for (var i = 0; i < rules.Length; i++)
            {
                var rule = rules[i];
                ruleTablePackedNCellBuffer.SetData(
                    rule.tablePackedNCell,
                    0,
                    i * rule.tablePackedNCell.Length,
                    rule.tablePackedNCell.Length);
            }
        }

        var spacetimePackedBufferSize =
            rules.Length * spaceSizePacked * (inPlace ? 2 : timeSize);

        ComputeShaderEx.EnsureBuffer(
            ref spacetimePackedBuffer, spacetimePackedBufferSize, sizeof(int));
        ComputeShaderEx.EnsureBuffer(
            ref flagBuffer, 1, sizeof(int));

        shader.Set("_RandSeed", randSeed);
        shader.Set("_SpaceSize", spaceSize);
        shader.Set("_TimeSize", inPlace ? 2 : timeSize);
        shader.Set("_TimeTo", timeSize);

        var fillStartRandomKernel = this.fillStartRandomKernel;

        fillStartRandomKernel.SetBuffer(
            "_SpacetimePacked", spacetimePackedBuffer);
        fillStartRandomKernel.Dispatch(spaceSizePacked, rules.Length);

        var emulateKernelName = "CSEmulate";
        var emulateKernel     =
            new ShaderKernel(shader, emulateKernelName);

        emulateKernel.Set(
            "_SpacetimePacked", spacetimePackedBuffer);
        emulateKernel.Set(
            "_Flag", flagBuffer);
        emulateKernel.Set(
            "_RuleTablePackedNCell", ruleTablePackedNCellBuffer);
        var tnr = Rule.timeNeighbourhoodRadius;

        for (var t = tnr; t < timeSize; t += timestepsPerCall)
        {
            shader.SetInt("_TimeStep", t);
            emulateKernel.Dispatch(
                spaceSizePacked,
                rules.Length);
        }

        var data = new int[1];

        flagBuffer.GetData(data);
    }
示例#6
0
    void Update()
    {
        if (!m_CS)
        {
            return;
        }
        if (!m_Shader)
        {
            return;
        }
        var sourceTex = m_Source.texture;

        if (!sourceTex)
        {
            return;
        }

        if (!m_RT)
        {
            m_KernelCopy   = m_CS.FindKernel("CSCopy");
            m_KernelMutate = m_CS.FindKernel("CSMutate");
            m_KernelScore  = m_CS.FindKernel("CSCalcScore");
            uint dummyY, dummyZ;
            m_CS.GetKernelThreadGroupSizes(m_KernelCopy, out m_GroupsizeCopy, out dummyY, out dummyZ);
            m_CS.GetKernelThreadGroupSizes(m_KernelScore, out m_GroupsizeScoreX, out m_GroupsizeScoreY, out dummyZ);

            var desc = new RenderTextureDescriptor
            {
                width             = sourceTex.width,
                height            = sourceTex.height,
                dimension         = TextureDimension.Tex2D,
                volumeDepth       = 1,
                msaaSamples       = 1,
                enableRandomWrite = true
            };
            m_RT = new RenderTexture(desc);
            m_RT.Create();
            m_DestImage.texture = m_RT;
            m_RTBest            = new RenderTexture(desc);
            m_RTBest.Create();
            m_BestImage.texture = m_RTBest;
            m_CS.SetTexture(m_KernelScore, "_SourceTex", sourceTex);
            m_CS.SetTexture(m_KernelScore, "_DestTex", m_RT);
            m_Log = $"{sourceTex.name} tris: {m_Triangles}\n";
        }

        if (m_DNA == null)
        {
            m_DNA = new ComputeBuffer(m_Triangles * 2, Marshal.SizeOf(typeof(Triangle)));
            var initData = new Triangle[m_Triangles * 2];
            Random.InitState(1);
            for (var i = 0; i < m_Triangles; ++i)
            {
                initData[i].posA          = new Vector2(Random.value, Random.value);
                initData[i].posB          = new Vector2(Random.value, Random.value);
                initData[i].posC          = new Vector2(Random.value, Random.value);
                initData[i].col           = new Color(Random.value, Random.value, Random.value, Random.value);
                initData[i + m_Triangles] = initData[i];
            }
            m_DNA.SetData(initData);
            m_CS.SetBuffer(m_KernelCopy, "_DNA", m_DNA);
            m_CS.SetBuffer(m_KernelMutate, "_DNA", m_DNA);
        }

        if (m_Params == null)
        {
            m_Params = new ComputeBuffer(1, Marshal.SizeOf(typeof(Params)));
            var para = new Params[1];
            para[0].triCount = m_Triangles;
            para[0].width    = sourceTex.width;
            para[0].height   = sourceTex.height;
            m_Params.SetData(para);

            m_CS.SetBuffer(m_KernelCopy, "_Params", m_Params);
            m_CS.SetBuffer(m_KernelMutate, "_Params", m_Params);
            m_CS.SetBuffer(m_KernelScore, "_Params", m_Params);
        }

        var sc = new Score[1];

        if (m_Score == null)
        {
            m_Score            = new ComputeBuffer(1, Marshal.SizeOf(typeof(Score)));
            sc[0].score        = 0xFFFFFFFF;
            sc[0].bestScore    = 0xFFFFFFFF;
            sc[0].iterations   = 0;
            sc[0].improvements = 0;
            sc[0].rng          = 1;
            m_Score.SetData(sc);

            m_CS.SetBuffer(m_KernelCopy, "_Score", m_Score);
            m_CS.SetBuffer(m_KernelMutate, "_Score", m_Score);
            m_CS.SetBuffer(m_KernelScore, "_Score", m_Score);
        }

        if (!m_Material)
        {
            m_Material = new Material(m_Shader);
            m_Material.SetBuffer("_DNA", m_DNA);
        }

        for (var it = 0; it < m_IterationsPerUpdate; ++it)
        {
            m_CS.Dispatch(m_KernelCopy, (m_Triangles + (int)m_GroupsizeCopy - 1) / (int)m_GroupsizeCopy, 1, 1);
            m_CS.Dispatch(m_KernelMutate, 1, 1, 1);

            Graphics.SetRenderTarget(m_RT);
            GL.Clear(false, true, Color.white);
            m_Material.SetInt("_StartVertex", 0);
            m_Material.SetPass(0);
            Graphics.DrawProcedural(MeshTopology.Triangles, m_Triangles * 3);

            m_CS.Dispatch(m_KernelScore, (sourceTex.width + (int)m_GroupsizeScoreX - 1) / (int)m_GroupsizeScoreX, (sourceTex.height + (int)m_GroupsizeScoreY - 1) / (int)m_GroupsizeScoreY, 1);
        }

        m_Score.GetData(sc);
        var fitness = (1.0 - sc[0].bestScore / (double)(sourceTex.width * sourceTex.height * 3 * 255)) * 100.0;
        var time    = Time.realtimeSinceStartup;

        m_Text.text = $"fit {fitness:F3}% time {time:F2}s\niter {sc[0].iterations} impr {sc[0].improvements}\n{m_Log}";
        var ifitness = (int)fitness;

        if (ifitness > m_GotFitness)
        {
            m_Log       += $"got {fitness:F3}% at time {time:F2}, iters {sc[0].iterations}\n";
            m_GotFitness = ifitness;
            Debug.Log(m_Log);
        }

        Graphics.SetRenderTarget(m_RTBest);
        GL.Clear(false, true, Color.white);
        m_Material.SetInt("_StartVertex", m_Triangles * 3);
        m_Material.SetPass(0);
        Graphics.DrawProcedural(MeshTopology.Triangles, m_Triangles * 3);
    }
示例#7
0
    //Membuat titik sampel beserta nilai density-nya
    //Creates sample points along its density value
    public void GenerateDensity()
    {
        Debug.ClearDeveloperConsole();
        totalTimeElapsed   = 0;
        timeDuration       = 0;
        timeStart          = 0;
        generatedMeshCount = numberOfGeneratedMeshObject.x * numberOfGeneratedMeshObject.y * numberOfGeneratedMeshObject.z;

        InitGeneratedMesh();
        Vector3 offset = Vector3.zero;
        int     index;

        //Buffer for sample points. Value for second parameter is based on Vector4 size in byte
        _pointsBuffer = new ComputeBuffer(_voxel.totalVertex, 16);
        //Buffer for line data. Value for second parameter is based on LineProperties struct's size in byte
        _linePropBuffer = new ComputeBuffer(_lineGenerator.line.Count, 52);
        //Buffer for line's node data. Value for second parameter is based on NodeProperties struct's size in byte
        _nodePositionBuffer = new ComputeBuffer(_lineGenerator.node.Count, 20);

        numThreadGroup.x = Mathf.CeilToInt(_voxel.numVertex.x / numThreads) + 1;
        numThreadGroup.y = Mathf.CeilToInt(_voxel.numVertex.y / numThreads) + 1;
        numThreadGroup.z = Mathf.CeilToInt(_voxel.numVertex.z / numThreads) + 1;

        for (int k = 0; k < numberOfGeneratedMeshObject.z; k++)
        {
            for (int j = 0; j < numberOfGeneratedMeshObject.y; j++)
            {
                for (int i = 0; i < numberOfGeneratedMeshObject.x; i++)
                {
                    timeStart = (float)System.DateTime.Now.Second + ((float)System.DateTime.Now.Millisecond / 1000);

                    offset.x = i * _voxel.boundaryWorldPos.x;
                    offset.y = j * _voxel.boundaryWorldPos.y;
                    offset.z = k * _voxel.boundaryWorldPos.z;
                    index    = i + (k * numberOfGeneratedMeshObject.x) + (j * (numberOfGeneratedMeshObject.x * numberOfGeneratedMeshObject.z));
                    SetGeneralInputs(_densityShader);

                    _linePropBuffer.SetData(_lineGenerator.GetLineProps());
                    _nodePositionBuffer.SetData(_lineGenerator.GetNodes());

                    _densityShader.SetBuffer(0, "nodeProps", _nodePositionBuffer);
                    _densityShader.SetBuffer(0, "lineProps", _linePropBuffer);
                    _densityShader.SetBool("isWorldSpaceNoise", isWorldSpaceNoise);
                    _densityShader.SetFloat("noiseIntensity", noiseIntensity);
                    _densityShader.SetFloat("noiseScale", noiseScale);
                    _densityShader.SetFloat("smoothingFactor", smoothingFactor);
                    _densityShader.SetVector("offset", offset);
                    _densityShader.Dispatch(0, numThreadGroup.x, numThreadGroup.y, numThreadGroup.z);
                    //_densityShader.Dispatch(0,_voxel.numVoxel.x+1,_voxel.numVoxel.y+1,_voxel.numVoxel.z+1);

                    _pointsDensity = new Vector4[_voxel.totalVertex];
                    _pointsBuffer.GetData(_pointsDensity);

                    //generatedMeshObjectsHolder.transform.GetChild(index).GetComponent<GeneratedMeshProperties>().Initiate();
                    GenerateMesh(index);
                }
            }
        }
        //Debug.Log("Total time elapsed: "+ totalTimeElapsed);
        if (showGeneratedVertexInfo)
        {
            ShowVoidVertex();
        }
        ReleaseBuffers();
    }
示例#8
0
    private void Update()
    {
        // TODO: do this on the GPU or figure out way to keep everything in local coor on the GPU (by setting external and collisions to local)
        // modify data to world coordinates
        for (int i = 0; i < numParticles; i++)
        {
            positions[i]  = transform.TransformPoint(positions[i]);
            velocities[i] = transform.TransformVector(velocities[i]);
        }
        positionsBuffer.SetData(positions);
        velocitiesBuffer.SetData(velocities);
        PBDClothSolver.SetVector("gravity", gravity);
        PBDClothSolver.SetFloat("invMass", invMass);
        PBDClothSolver.SetFloat("stretchStiffness", distanceStretchStiffness);
        PBDClothSolver.SetFloat("compressionStiffness", distanceCompressionStiffness);
        PBDClothSolver.SetFloat("bendingStiffness", bendingStiffness);


        // calculate the timestep
        nextFrameTime += Time.deltaTime;
        int iter = 0;

        while (nextFrameTime > 0)
        {
            if (nextFrameTime < timestep)
            {
                break;
            }

            float dt = Mathf.Min(nextFrameTime, timestep);
            nextFrameTime -= dt;
            iter++;

            // send the dt data to the GPU
            PBDClothSolver.SetFloat("dt", dt);

            // step 5: apply external forces
            PBDClothSolver.Dispatch(applyExternalForcesKernel, numGroups_Vertices, 1, 1);

            // step 6: damp velocity
            if (dampingMethod != DampingMethod.noDamping)
            {
                PBDClothSolver.Dispatch(dampVelocitiesKernel, numGroups_Vertices, 1, 1);
            }

            // step 7: apply explicit Euler to positions based on velocity
            PBDClothSolver.Dispatch(applyExplicitEulerKernel, numGroups_Vertices, 1, 1);

            // step 8: clear current collisions and generate new collisions
            SetupCollisionComputeBuffers();

            // step 9-11: project constraints iterationNum times
            for (int j = 0; j < iterationNum; j++)
            {
                // TODO: maybe shuffle here

                // distance constraints
                PBDClothSolver.Dispatch(projectConstraintDeltasKernel, numGroups_AllConstraints, 1, 1);
                PBDClothSolver.Dispatch(averageConstraintDeltasKernel, numGroups_Vertices, 1, 1);

                // collision constraints
                if (numCollidableSpheres > 0)
                {
                    PBDClothSolver.Dispatch(satisfySphereCollisionsKernel, numGroups_Vertices, 1, 1);
                }
                if (numCollidableCubes > 0)
                {
                    PBDClothSolver.Dispatch(satisfyCubeCollisionsKernel, numGroups_Vertices, 1, 1);
                }
            }

            // satisfy pointConstraints
            if (numPointConstraints > 0)
            {
                if (enableMouseInteraction && tempPointConstraint != -1)
                {
                    PBDClothSolver.SetBool("hasTempPointConstraint", true);
                    PBDClothSolver.SetVector("deltaPointConstraint", deltaPointConstraint);
                    PBDClothSolver.SetInt("tempPointConstraint", tempPointConstraint);
                }
                else
                {
                    PBDClothSolver.SetBool("hasTempPointConstraint", false);
                    PBDClothSolver.SetInt("tempPointConstraint", -1);
                }
                PBDClothSolver.Dispatch(satisfyPointConstraintsKernel, numGroups_PointConstraints, 1, 1);
            }

            // step 13 & 14: apply projected positions to actual vertices
            PBDClothSolver.Dispatch(updatePositionsKernel, numGroups_Vertices, 1, 1);

            // step 16: update all velocities using friction
            //ApplyFriction();
        }

        // handle mouse drag inputs
        if (enableMouseInteraction)
        {
            if (Input.GetMouseButtonDown(0) && tempPointConstraint == -1)
            {
                RaycastHit hit;
                Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                if (GetComponent <MeshCollider>().Raycast(ray, out hit, float.MaxValue))
                {
                    int vertex = triangles[hit.triangleIndex].vertices[0];
                    tempPointConstraint  = vertex;
                    lastMousePos         = Input.mousePosition;
                    deltaPointConstraint = Vector3.zero;
                }
                else if (GetComponentInChildren <MeshCollider>().Raycast(ray, out hit, float.MaxValue))
                {
                    int vertex = triangles[hit.triangleIndex].vertices[0];
                    tempPointConstraint  = vertex;
                    lastMousePos         = Input.mousePosition;
                    deltaPointConstraint = Vector3.zero;
                }
            }
            else if (Input.GetMouseButtonUp(0))
            {
                tempPointConstraint = -1;
            }
            else if (tempPointConstraint != -1)
            {
                deltaPointConstraint    = Input.mousePosition - lastMousePos;
                deltaPointConstraint   *= 0.001f;
                deltaPointConstraint.x *= -1;
                lastMousePos            = Input.mousePosition;
                if (Input.GetKey(KeyCode.I))
                {
                    deltaPointConstraint.z -= 0.01f;
                }
                if (Input.GetKey(KeyCode.K))
                {
                    deltaPointConstraint.z += 0.01f;
                }
                if (Input.GetKey(KeyCode.J))
                {
                    deltaPointConstraint.x += 0.01f;
                }
                if (Input.GetKey(KeyCode.L))
                {
                    deltaPointConstraint.x -= 0.01f;
                }
                if (Input.GetKey(KeyCode.U))
                {
                    deltaPointConstraint.y += 0.01f;
                }
                if (Input.GetKey(KeyCode.O))
                {
                    deltaPointConstraint.y -= 0.01f;
                }
            }
        }


        // get data from GPU back to CPU
        positionsBuffer.GetData(positions);
        velocitiesBuffer.GetData(velocities);

        // recalculate the center of the mesh
        Vector3 newCenter = Vector3.zero;
        Vector3 delta     = Vector3.zero;

        if (pointConstraintType == PointConstraintType.none)
        {
            newCenter = GetComponentInChildren <Renderer>().bounds.center;
            delta     = newCenter - transform.position;
        }

        // modify data to back to local coordinates
        for (int i = 0; i < numParticles; i++)
        {
            positions[i]  = transform.InverseTransformPoint(positions[i] - delta);
            velocities[i] = transform.InverseTransformVector(velocities[i]);
        }

        if (pointConstraintType == PointConstraintType.none)
        {
            transform.position = newCenter;
        }

        // update everything into Unity
        mesh.vertices = positions;
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        reverseMesh.vertices = positions;
        Vector3[] reverseNormals = mesh.normals;
        for (int i = 0; i < reverseNormals.Length; i++)
        {
            reverseNormals[i] *= -1;
        }
        reverseMesh.normals = reverseNormals;

        GetComponent <MeshCollider>().sharedMesh           = mesh;
        GetComponentInChildren <MeshCollider>().sharedMesh = reverseMesh;
    }
示例#9
0
        /// <summary>
        /// Batch update. Reconstruct all meshes needed by running GPU based Marching Cubes
        /// </summary>
        public void BatchUpdate()
        {
            for (int x = 0; x < width / blockSize; x++)
            {
                for (int y = 0; y < height / blockSize; y++)
                {
                    for (int z = 0; z < length / blockSize; z++)
                    {
                        if (_blocks[x, y, z] == null)
                        {
                            continue;
                        }
                        if (_blocks[x, y, z].GetComponent <MeshFilter>().mesh != null)
                        {
                            _blocks[x, y, z].GetComponent <MeshFilter>().mesh.Clear();
                        }
                        //if (_blocks[x, y, z].GetComponent<MeshCollider>().sharedMesh != null)
                        //    _blocks[x, y, z].GetComponent<MeshCollider>().sharedMesh.Clear();
                    }
                }
            }

            shaderSample.SetBuffer(_kernelCollectSurfaceBlock, "_Particles", sphSolver._bufferParticles);
            _bufferSufaceBlocks.SetData(_surfaceBlocksInit);
            shaderSample.SetBuffer(_kernelCollectSurfaceBlock, "_SurfaceMCBlocks", _bufferSufaceBlocks);
            shaderSample.Dispatch(_kernelCollectSurfaceBlock, sphSolver._sphthreadGroupNum, 1, 1);
            _bufferSufaceBlocks.GetData(_surfaceBlocksContainer);
            _nextUpdateblocks.Clear();

            for (int i = 0; i < _surfaceBlocksContainer.Length; ++i)
            {
                if (_surfaceBlocksContainer[i] == 1)
                {
                    int x = i / (blockDimY * blockDimZ);
                    int y = (i - x * (blockDimY * blockDimZ)) / blockDimZ;
                    int z = i - x * (blockDimY * blockDimZ) - y * blockDimZ;
                    _nextUpdateblocks.Add(new Int3(x, y, z));
                }
            }

            //for (int x = 0; x < blockDimX; ++x)
            //    for (int y = 0; y < blockDimY; ++y)
            //        for (int z = 0; z < blockDimZ; ++z)
            //            _nextUpdateblocks.Add(new Int3(x, y, z));

            if (_nextUpdateblocks.Count == 0)
            {
                return;
            }

            //GPU sampling
            ComputeBuffer bufferBlocks = new ComputeBuffer(_nextUpdateblocks.Count, sizeof(int) * 3);

            bufferBlocks.SetData(_nextUpdateblocks.ToArray());


            //List<CSParticle> particlesCopy = new List<CSParticle>();

            //int[] particlesStartIdx = new int[sphSolver.gridCountXYZ + 1];

            //int startIdx = 0;
            //for (int x = 0; x < sphSolver.gridSize._x; ++x)
            //    for (int y = 0; y < sphSolver.gridSize._y; ++y)
            //        for (int z = 0; z < sphSolver.gridSize._z; ++z)
            //        {
            //            int idx = x * sphSolver.gridCountYZ + y * sphSolver.gridSize._z + z;
            //            foreach (var particle in sphSolver.grid[idx].particles)
            //            {
            //                particlesCopy.Add(new CSParticle((float)particle.mass, 1f / (float)particle.density,
            //                    new Vector3((float)particle.position.x, (float)particle.position.y, (float)particle.position.z)));
            //            }
            //            particlesStartIdx[idx] = startIdx;
            //            startIdx += sphSolver.grid[idx].particles.Count;
            //        }
            //particlesStartIdx[particlesStartIdx.Length - 1] = sphSolver.currParticleNum;

            //_bufferParticlesStartIndex.SetData(particlesStartIdx);
            //_bufferParticles.SetData(particlesCopy.ToArray());

            ComputeBuffer bufferSamples = new ComputeBuffer(_nextUpdateblocks.Count * (ag1BlockSize) * (ag1BlockSize) * (ag1BlockSize), sizeof(float));
            ComputeBuffer bufferNormals = new ComputeBuffer(_nextUpdateblocks.Count * (ag1BlockSize) * (ag1BlockSize) * (ag1BlockSize), sizeof(float) * 3);

            shaderSample.SetBuffer(sampleKernel, "_Blocks", bufferBlocks);
            shaderSample.SetBuffer(sampleKernel, "_ParticleCellNumPrefixSum", sphSolver._bufferParticleNumPerCell);
            shaderSample.SetBuffer(sampleKernel, "_Particles", sphSolver._bufferParticles);
            shaderSample.SetBuffer(sampleKernel, "_Samples", bufferSamples);
            shaderSample.SetBuffer(sampleKernel, "_Normals", bufferNormals);

            shaderSample.Dispatch(sampleKernel, _nextUpdateblocks.Count, 1, 1);

            bufferBlocks.Release();
            bufferBlocks = null;

            //marching-cube

            //STAGE I: collect triangle number
            ComputeBuffer bufferTriNum = new ComputeBuffer(1, sizeof(int));

            bufferTriNum.SetData(new int[] { 0 });
            ComputeBuffer bufferCornerFlags = new ComputeBuffer(_nextUpdateblocks.Count * blockSize * blockSize * blockSize, sizeof(int));

            shaderCollectTriNum.SetBuffer(ctnKernel, "_Samples", bufferSamples);
            shaderCollectTriNum.SetBuffer(ctnKernel, "_CornerToTriNumTable", _bufferCornerToTriNumTable);
            shaderCollectTriNum.SetBuffer(ctnKernel, "_TriNum", bufferTriNum);
            shaderCollectTriNum.SetBuffer(ctnKernel, "_CornerFlags", bufferCornerFlags);

            shaderCollectTriNum.Dispatch(ctnKernel, _nextUpdateblocks.Count, 1, 1);

            int[] triNum = new int[1];
            bufferTriNum.GetData(triNum);
            if (triNum[0] == 0)
            {
                //no triangles, early exit

                bufferNormals.Release();
                bufferSamples.Release();

                bufferTriNum.Release();
                bufferCornerFlags.Release();
                return;
            }
//#if UNITY_EDITOR
//            //Debug.Log("triangles count " + triNum[0]);
//#endif
            //STAGE II: do marching cube
            ComputeBuffer bufferMeshes      = new ComputeBuffer(triNum[0], CSTriangle.stride);
            ComputeBuffer bufferTriEndIndex = new ComputeBuffer(1, sizeof(int));

            bufferTriEndIndex.SetData(new int[] { 0 });
            ComputeBuffer bufferTriBlockNum = new ComputeBuffer(_nextUpdateblocks.Count, sizeof(int));

            int[] triBlockNum = new int[_nextUpdateblocks.Count];
            bufferTriBlockNum.SetData(triBlockNum);

            shaderMarchingCube.SetBuffer(mcKernel, "_Samples", bufferSamples);
            shaderMarchingCube.SetBuffer(mcKernel, "_Normals", bufferNormals);
            shaderMarchingCube.SetBuffer(mcKernel, "_CornerFlags", bufferCornerFlags);
            shaderMarchingCube.SetBuffer(mcKernel, "_CornerToEdgeTable", _bufferCornerToEdgeTable);
            shaderMarchingCube.SetBuffer(mcKernel, "_CornerToVertTable", _bufferCornerToVertTable);
            shaderMarchingCube.SetBuffer(mcKernel, "_Meshes", bufferMeshes);
            shaderMarchingCube.SetBuffer(mcKernel, "_TriEndIndex", bufferTriEndIndex);
            shaderMarchingCube.SetBuffer(mcKernel, "_TriBlockNum", bufferTriBlockNum);
            //dispatch compute shader
            shaderMarchingCube.Dispatch(mcKernel, _nextUpdateblocks.Count, 1, 1);

            //split bufferMeshes to meshes for individual blocks
            CSTriangle[] csTriangles = new CSTriangle[triNum[0]];//triNum[0] is the counter
            bufferMeshes.GetData(csTriangles);
            bufferTriBlockNum.GetData(triBlockNum);
            int[] triBlockCounter = new int[triBlockNum.Length];

            Vector3[][] vertices = new Vector3[_nextUpdateblocks.Count][];
            Vector3[][] normals  = new Vector3[_nextUpdateblocks.Count][];
            for (int i = 0; i < _nextUpdateblocks.Count; i++)
            {
                vertices[i] = new Vector3[3 * triBlockNum[i]];
                normals[i]  = new Vector3[3 * triBlockNum[i]];
            }
            foreach (var vt in csTriangles)
            {
                vertices[vt.block][triBlockCounter[vt.block]] = vt.position0 * engineScale;
                normals[vt.block][triBlockCounter[vt.block]]  = vt.normal0;
                triBlockCounter[vt.block]++;

                vertices[vt.block][triBlockCounter[vt.block]] = vt.position1 * engineScale;
                normals[vt.block][triBlockCounter[vt.block]]  = vt.normal1;
                triBlockCounter[vt.block]++;

                vertices[vt.block][triBlockCounter[vt.block]] = vt.position2 * engineScale;
                normals[vt.block][triBlockCounter[vt.block]]  = vt.normal2;
                triBlockCounter[vt.block]++;
            }

            for (int i = 0; i < _nextUpdateblocks.Count; i++)
            {
                var x = _nextUpdateblocks[i]._x;
                var y = _nextUpdateblocks[i]._y;
                var z = _nextUpdateblocks[i]._z;
                _blocks[x, y, z].GetComponent <MeshFilter>().mesh.Clear(false);
                var mesh = _blocks[x, y, z].GetComponent <MeshFilter>().mesh;

                mesh.vertices = vertices[i];
                int[] idx = new int[vertices[i].Length];
                Buffer.BlockCopy(_incSequence, 0, idx, 0, vertices[i].Length * sizeof(int));
                mesh.SetTriangles(idx, 0);
                mesh.normals = normals[i];
                mesh.Optimize();
                mesh.RecalculateBounds();
                // _blocks[x, y, z].GetComponent<MeshFilter>().mesh = mesh;
                _blocks[x, y, z].GetComponent <MeshRenderer>().material = material;
                //_blocks[x, y, z].GetComponent<MeshCollider>().sharedMesh = mesh;
            }

            //Debug.Log("Time taken: " + (Time.realtimeSinceStartup - startTime) * 1000.0f);
//#if UNITY_EDITOR
//            print("Time taken: " + (Time.realtimeSinceStartup - startTime) * 1000.0f);
//#endif
            bufferNormals.Release();
            bufferSamples.Release();

            bufferTriNum.Release();
            bufferCornerFlags.Release();

            bufferMeshes.Release();
            bufferTriEndIndex.Release();
            bufferTriBlockNum.Release();

            GC.Collect();
        }
示例#10
0
        private void GenerateWavesSpectrum()
        {
            // Slope variance due to all waves, by integrating over the full spectrum.
            // Used by the BRDF rendering model
            float theoreticSlopeVariance = 0.0f;
            float k = 5e-3f;

            while (k < 1e3f)
            {
                float nextK = k * 1.001f;
                theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k);
                k = nextK;
            }

            float[] spectrum01 = new float[m_fourierGridSize * m_fourierGridSize * 4];
            float[] spectrum23 = new float[m_fourierGridSize * m_fourierGridSize * 4];

            int     idx;
            float   i;
            float   j;
            float   totalSlopeVariance = 0.0f;
            Vector2 sample12XY;
            Vector2 sample12ZW;
            Vector2 sample34XY;
            Vector2 sample34ZW;

            Random.InitState(0);


            for (int x = 0; x < m_fourierGridSize; x++)
            {
                for (int y = 0; y < m_fourierGridSize; y++)
                {
                    idx = x + y * m_fourierGridSize;
                    i   = (x >= m_fourierGridSize / 2) ? (float)(x - m_fourierGridSize) : (float)x;
                    j   = (y >= m_fourierGridSize / 2) ? (float)(y - m_fourierGridSize) : (float)y;

                    sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x);
                    sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x);
                    sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y);
                    sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z);

                    spectrum01[idx * 4 + 0] = sample12XY.x;
                    spectrum01[idx * 4 + 1] = sample12XY.y;
                    spectrum01[idx * 4 + 2] = sample12ZW.x;
                    spectrum01[idx * 4 + 3] = sample12ZW.y;

                    spectrum23[idx * 4 + 0] = sample34XY.x;
                    spectrum23[idx * 4 + 1] = sample34XY.y;
                    spectrum23[idx * 4 + 2] = sample34ZW.x;
                    spectrum23[idx * 4 + 3] = sample34ZW.y;

                    i *= 2.0f * Mathf.PI;
                    j *= 2.0f * Mathf.PI;

                    totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY);
                    totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW);
                    totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY);
                    totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW);
                }
            }

            //Write floating point data into render texture
            ComputeBuffer buffer = new ComputeBuffer(m_fourierGridSize * m_fourierGridSize, sizeof(float) * 4);

            buffer.SetData(spectrum01);
            CBUtility.WriteIntoRenderTexture(m_spectrum01, 4, buffer, World.WriteData);

            buffer.SetData(spectrum23);
            CBUtility.WriteIntoRenderTexture(m_spectrum23, 4, buffer, World.WriteData);

            buffer.Release();

            m_varianceShader.SetFloat("_SlopeVarianceDelta", 0.5f * (theoreticSlopeVariance - totalSlopeVariance));
            m_varianceShader.SetFloat("_VarianceSize", (float)m_varianceSize);
            m_varianceShader.SetFloat("_Size", m_fsize);
            m_varianceShader.SetVector("_GridSizes", m_gridSizes);
            m_varianceShader.SetTexture(0, "_Spectrum01", m_spectrum01);
            m_varianceShader.SetTexture(0, "_Spectrum23", m_spectrum23);
            m_varianceShader.SetTexture(0, "des", m_variance);

            m_varianceShader.Dispatch(0, m_varianceSize / 4, m_varianceSize / 4, m_varianceSize / 4);

            //Find the maximum value for slope variance

            buffer = new ComputeBuffer(m_varianceSize * m_varianceSize * m_varianceSize, sizeof(float));
            CBUtility.ReadFromRenderTexture(m_variance, 1, buffer, World.ReadData);

            float[] varianceData = new float[m_varianceSize * m_varianceSize * m_varianceSize];
            buffer.GetData(varianceData);

            m_maxSlopeVariance = 0.0f;
            for (int v = 0; v < m_varianceSize * m_varianceSize * m_varianceSize; v++)
            {
                m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, varianceData[v]);
            }

            buffer.Release();
        }
    private Texture3D ComputeSDF()
    {
        // Create the voxel texture.
        Texture3D voxels = new Texture3D(resolution, resolution, resolution, TextureFormat.RGBAHalf, false);
        voxels.anisoLevel = 1;
        voxels.filterMode = FilterMode.Bilinear;
        voxels.wrapMode = TextureWrapMode.Clamp;
        
        // Get an array of pixels from the voxel texture, create a buffer to
        // hold them, and upload the pixels to the buffer.
        Color[] pixelArray = voxels.GetPixels(0);
        ComputeBuffer pixelBuffer = new ComputeBuffer(pixelArray.Length, sizeof(float) * 4);
        pixelBuffer.SetData(pixelArray);

        // Get an array of triangles from the mesh.
        Vector3[] meshVertices = mesh.vertices;
        int[] meshTriangles = mesh.GetTriangles(subMeshIndex);
        Triangle[] triangleArray = new Triangle[meshTriangles.Length / 3];
        for (int t = 0; t < triangleArray.Length; t++)
        {
            triangleArray[t].a = meshVertices[meshTriangles[3 * t + 0]] - mesh.bounds.center;
            triangleArray[t].b = meshVertices[meshTriangles[3 * t + 1]] - mesh.bounds.center;
            triangleArray[t].c = meshVertices[meshTriangles[3 * t + 2]] - mesh.bounds.center;
        }

        // Create a buffer to hold the triangles, and upload them to the buffer.
        ComputeBuffer triangleBuffer = new ComputeBuffer(triangleArray.Length, sizeof(float) * 3 * 3);
        triangleBuffer.SetData(triangleArray);

        // Instantiate the compute shader from resources.
        ComputeShader compute = (ComputeShader)Instantiate(Resources.Load("SDF"));
        int kernel = compute.FindKernel("CSMain");

        // Upload the pixel buffer to the GPU.
        compute.SetBuffer(kernel, "pixelBuffer", pixelBuffer);
        compute.SetInt("pixelBufferSize", pixelArray.Length);

        // Upload the triangle buffer to the GPU.
        compute.SetBuffer(kernel, "triangleBuffer", triangleBuffer);
        compute.SetInt("triangleBufferSize", triangleArray.Length);

        // Calculate and upload the other necessary parameters.
        float maxMeshSize = Mathf.Max(Mathf.Max(mesh.bounds.size.x, mesh.bounds.size.y), mesh.bounds.size.z);
        float totalUnitsInTexture = maxMeshSize + 2.0f * padding;
        compute.SetInt("textureSize", resolution);
        compute.SetFloat("totalUnitsInTexture", totalUnitsInTexture);

        // Compute the SDF.
        compute.Dispatch(kernel, pixelArray.Length / 256 + 1, 1, 1);

        // Destroy the compute shader and release the triangle buffer.
        DestroyImmediate(compute);
        triangleBuffer.Release();

        // Retrieve the pixel buffer and reapply it to the voxels texture.
        pixelBuffer.GetData(pixelArray);
        pixelBuffer.Release();
        voxels.SetPixels(pixelArray, 0);
        voxels.Apply();

        // Return the voxels texture.
        return voxels;
    }
示例#12
0
    void Update()
    {
        if (s_update_count++ == 0)
        {
            MPGPEmitter.UpdateAll();
            MPGPForce.UpdateAll();
            MPGPColliderBase.UpdateAll();
        }

        if (m_writeback_to_cpu)
        {
            m_buf_particles[0].GetData(m_particles);
            m_buf_world_idata.GetData(m_world_idata);

            m_actions.ForEach((a) => { a.Invoke(); });
            m_onetime_actions.ForEach((a) => { a.Invoke(); });
            m_onetime_actions.Clear();

            m_buf_particles[0].SetData(m_particles);
            m_buf_world_idata.SetData(m_world_idata);
        }


        m_world_data[0].num_max_particles = m_max_particles;
        m_world_data[0].SetWorldSize(transform.position, transform.localScale,
                                     (uint)m_world_div_x, (uint)m_world_div_y, (uint)m_world_div_z);
        m_world_data[0].timestep              = Time.deltaTime * m_timescale;
        m_world_data[0].particle_size         = m_particle_radius;
        m_world_data[0].particle_lifetime     = m_lifetime;
        m_world_data[0].num_sphere_colliders  = m_sphere_colliders.Count;
        m_world_data[0].num_capsule_colliders = m_capsule_colliders.Count;
        m_world_data[0].num_box_colliders     = m_box_colliders.Count;
        m_world_data[0].num_forces            = m_forces.Count;
        m_world_data[0].damping            = m_damping;
        m_world_data[0].advection          = m_advection;
        m_world_data[0].coord_scaler       = m_coord_scaler;
        m_world_data[0].wall_stiffness     = m_wall_stiffness;
        m_world_data[0].gbuffer_stiffness  = m_gbuffer_stiffness;
        m_world_data[0].gbuffer_thickness  = m_gbuffer_thickness;
        m_world_data[0].pressure_stiffness = m_pressure_stiffness;
        if (m_gbuffer_data != null)
        {
            var cam = m_gbuffer_data.GetCamera();
            m_world_data[0].view_proj     = m_gbuffer_data.GetMatrix_VP();
            m_world_data[0].inv_view_proj = m_gbuffer_data.GetMatrix_InvVP();
            m_world_data[0].rt_size       = new Vector2(cam.pixelWidth, cam.pixelHeight);
        }


        m_sph_params[0].smooth_len         = m_sph_smoothlen;
        m_sph_params[0].particle_mass      = m_sph_particleMass;
        m_sph_params[0].pressure_stiffness = m_sph_pressureStiffness;
        m_sph_params[0].rest_density       = m_sph_restDensity;
        m_sph_params[0].viscosity          = m_sph_viscosity;

        m_buf_sphere_colliders.SetData(m_sphere_colliders.ToArray());   m_sphere_colliders.Clear();
        m_buf_capsule_colliders.SetData(m_capsule_colliders.ToArray()); m_capsule_colliders.Clear();
        m_buf_box_colliders.SetData(m_box_colliders.ToArray());         m_box_colliders.Clear();
        m_buf_forces.SetData(m_forces.ToArray());                       m_forces.Clear();

        int num_cells = m_world_data[0].world_div_x * m_world_data[0].world_div_y * m_world_data[0].world_div_z;

        m_world_data[0].num_additional_particles = m_particles_to_add.Count;
        m_buf_world_data.SetData(m_world_data);
        MPGPWorldData csWorldData = m_world_data[0];

        m_buf_sph_params.SetData(m_sph_params);


        // add new particles
        if (m_particles_to_add.Count > 0)
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = kAddParticles;
            m_buf_particles_to_add.SetData(m_particles_to_add.ToArray());
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "particles_to_add", m_buf_particles_to_add);
            cs.Dispatch(kernel, m_particles_to_add.Count / BLOCK_SIZE + 1, 1, 1);
            m_particles_to_add.Clear();
        }

        {
            // clear cells
            {
                ComputeShader cs     = m_cs_hashgrid;
                int           kernel = 0;
                cs.SetBuffer(kernel, "cells_rw", m_buf_cells);
                cs.Dispatch(kernel, num_cells / BLOCK_SIZE, 1, 1);
            }
            // generate hashes
            {
                ComputeShader cs     = m_cs_hashgrid;
                int           kernel = 1;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "sort_keys_rw", m_buf_sort_data[0]);
                cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
            }
            // sort keys
            {
                m_bitonic_sort.BitonicSort(m_buf_sort_data[0], m_buf_sort_data[1], (uint)csWorldData.num_max_particles);
            }
            // reorder particles
            {
                ComputeShader cs     = m_cs_hashgrid;
                int           kernel = 2;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "particles_rw", m_buf_particles[1]);
                cs.SetBuffer(kernel, "sort_keys", m_buf_sort_data[0]);
                cs.SetBuffer(kernel, "cells_rw", m_buf_cells);
                cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
            }
            // copy back
            {
                ComputeShader cs     = m_cs_hashgrid;
                int           kernel = 3;
                cs.SetBuffer(kernel, "particles", m_buf_particles[1]);
                cs.SetBuffer(kernel, "particles_rw", m_buf_particles[0]);
                cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
            }
        }


        //{
        //	dbgSortData = new GPUSort.KIP[csWorldData.num_max_particles];
        //	cbSortData[0].GetData(dbgSortData);
        //	uint prev = 0;
        //	for (int i = 0; i < dbgSortData.Length; ++i)
        //	{
        //		if (prev > dbgSortData[i].key)
        //		{
        //			Debug.Log("sort bug: "+i);
        //			break;
        //		}
        //		prev = dbgSortData[i].key;
        //	}
        //}
        //dbgCellData = new CellData[num_cells];
        //cbCells.GetData(dbgCellData);
        //for (int i = 0; i < num_cells; ++i )
        //{
        //	if (dbgCellData[i].begin!=0)
        //	{
        //		Debug.Log("dbgCellData:" + dbgCellData[i].begin + "," + dbgCellData[i].end);
        //		break;
        //	}
        //}

        int num_active_blocks = m_max_particles / BLOCK_SIZE;

        // initialize intermediate data
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = kPrepare;
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "pimd", m_buf_imd);
            cs.SetBuffer(kernel, "cells", m_buf_cells);
            cs.Dispatch(kernel, num_active_blocks, 1, 1);
        }

        // particle interaction
        if (m_solver == MPGPWorld.Interaction.Impulse)
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                                   kProcessInteraction_Impulse : kProcessInteraction_Impulse2D;
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "pimd", m_buf_imd);
            cs.SetBuffer(kernel, "cells", m_buf_cells);
            cs.Dispatch(kernel, num_active_blocks, 1, 1);
        }
        else if (m_solver == MPGPWorld.Interaction.SPH)
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                                   kProcessInteraction_SPH_Pass1 : kProcessInteraction_SPH_Pass12D;
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "sph_params", m_buf_sph_params);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "pimd", m_buf_imd);
            cs.SetBuffer(kernel, "cells", m_buf_cells);
            cs.Dispatch(kernel, num_active_blocks, 1, 1);

            kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                     kProcessInteraction_SPH_Pass2 : kProcessInteraction_SPH_Pass22D;
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "sph_params", m_buf_sph_params);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "pimd", m_buf_imd);
            cs.SetBuffer(kernel, "cells", m_buf_cells);
            cs.Dispatch(kernel, num_active_blocks, 1, 1);
        }
        else if (m_solver == MPGPWorld.Interaction.None)
        {
            // do nothing
        }

        // gbuffer collision
        if (m_process_gbuffer_collision && m_gbuffer_data != null)
        {
            var depth  = m_gbuffer_data.GetGBuffer_Depth();
            var normal = m_gbuffer_data.GetGBuffer_Normal();
            if (depth != null && normal != null)
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = kProcessGBufferCollision;
                cs.SetTexture(kernel, "gbuffer_normal", normal);
                cs.SetTexture(kernel, "gbuffer_depth", depth);
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
            else
            {
                m_gbuffer_data.m_enable_inv_matrices = true;
                m_gbuffer_data.m_enable_prev_depth   = true;
                m_gbuffer_data.m_enable_prev_normal  = true;
            }
        }

        // colliders
        if (m_process_colliders)
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = kProcessColliders;
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "pimd", m_buf_imd);
            cs.SetBuffer(kernel, "cells", m_buf_cells);
            cs.SetBuffer(kernel, "sphere_colliders", m_buf_sphere_colliders);
            cs.SetBuffer(kernel, "capsule_colliders", m_buf_capsule_colliders);
            cs.SetBuffer(kernel, "box_colliders", m_buf_box_colliders);
            cs.Dispatch(kernel, num_active_blocks, 1, 1);
        }

        // forces
        if (m_process_forces)
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = kProcessForces;
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "pimd", m_buf_imd);
            cs.SetBuffer(kernel, "cells", m_buf_cells);
            cs.SetBuffer(kernel, "forces", m_buf_forces);
            cs.Dispatch(kernel, num_active_blocks, 1, 1);
        }

        // integrate
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = kIntegrate;
            cs.SetBuffer(kernel, "world_data", m_buf_world_data);
            cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
            cs.SetBuffer(kernel, "pimd", m_buf_imd);
            cs.Dispatch(kernel, num_active_blocks, 1, 1);
        }
    }
    protected override void Init()
    {
        base.Init();

        MotionType = MotionType.MultiDepth;
        // Camera.main.fieldOfView = 30f;

        _touchIds = new Dictionary <int, ClickData>();
        PosAndDir[] datas = new PosAndDir[ComputeBuffer.count];

        ComputeBuffer.GetData(datas);

        List <PosAndDir> temp        = new List <PosAndDir>();
        List <PosAndDir> allDataList = new List <PosAndDir>();



        //这里注意,posAndDir属于结构体,值拷贝
        for (int i = 0; i < datas.Length; i++)
        {
            PosAndDir data = datas[i];
            if (i < Common.PictureCount * 3)
            {
                temp.Add(data);//编号一样的单独拿出来
            }
            else
            {
                data.position    = Vector4.zero;//其他编号都隐藏
                data.originalPos = Vector4.one;
                allDataList.Add(data);
            }
        }
        _zeroIndexCount = allDataList.Count;
        PosAndDir[] newData = temp.ToArray();
        int         stride  = Marshal.SizeOf(typeof(DepthInfo));

        _depthBuffer = new ComputeBuffer(3, stride);
        _depths      = new DepthInfo[3];

        //点击缓存
        _clickPointBuff = new ComputeBuffer(1, Marshal.SizeOf(typeof(PosAndDir)));
        PosAndDir[] clickPoint = { new PosAndDir(-1) };
        _clickPointBuff.SetData(clickPoint);

        int   k      = 0;
        float z      = 6;
        float scaleY = 1;//y轴位置屏幕有内容的比率

        //得到随机点的个数,第一层的随机点个数不允许低于40
        //这个参数存在的意义是Common.Sample2D方法采样的时候会得不到正确的个数,有时候明显偏低,这个参数就是为了修正这个数据
        //这个数据如果scaleY s 两个参数有变化,应该考虑第一层随机点个数的变化
        int            count     = 40;
        List <Vector2> randomPos = new List <Vector2>();

        for (int j = 0; j < newData.Length; j++)
        {
            if (j % Common.PictureCount == 0)
            {
                //距离相机的深度值
                float tempZ = k * z - 4;
                k++;
                _screenPosLeftDown  = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, tempZ - Camera.main.transform.position.z));
                _screenPosLeftUp    = Camera.main.ScreenToWorldPoint(new Vector3(0, Height, tempZ - Camera.main.transform.position.z));
                _screenPosRightDown = Camera.main.ScreenToWorldPoint(new Vector3(Width, 0, tempZ - Camera.main.transform.position.z));
                _screenPosRightUp   = Camera.main.ScreenToWorldPoint(new Vector3(Width, Height, tempZ - Camera.main.transform.position.z));

                float s = 1f; //不同层次的给定不同的缩放
                float a = 1f; //不同层次的给定不同的透明度
                if (k == 1)
                {
                    s      = 1f;
                    a      = 1f;
                    scaleY = 0.55f;
                }
                else if (k == 2)
                {
                    s      = 1.2f;
                    a      = 0.45f;
                    scaleY = 0.25f;
                }
                else if (k == 3)
                {
                    s      = 1.4f;
                    a      = 0.25f;
                    scaleY = 0.18f;
                }
                else if (k == 4)
                {
                    s      = 1.6f;
                    a      = 0.45f;
                    scaleY = 0.7f;
                }
                else if (k == 5)
                {
                    s      = 1.8f;
                    a      = 0.25f;
                    scaleY = 0.6f;
                }



                while (true)
                {
                    if (count >= randomPos.Count)//如果得到的个数比上一个还小,那是不正确的采样,必须重新采样
                    {
                        // Debug.Log("x:" + _screenPosRightDown.x + " \r\n x1:" + _screenPosLeftDown.x + " \r\n  y:" + _screenPosLeftUp.y + "\r\n  y1:" + _screenPosLeftDown.y + " \r\n scaleY:" + scaleY + " \r\n  s:" + s);
                        randomPos = Common.Sample2D((_screenPosRightDown.x - _screenPosLeftDown.x) * 4, (_screenPosLeftUp.y - _screenPosLeftDown.y) * scaleY, s + 0.75f, 25);
                    }
                    else
                    {
                        count = randomPos.Count;
                        break;
                    }
                }



                Debug.Log("randomPos count is  " + randomPos.Count + " 层级为=> " + (k - 1) + "   tempZ is=>" + tempZ);
                _depths[k - 1] = new DepthInfo(k - 1, tempZ, s, a);
            }



            float rangeZ = Random.Range(-0.5f, 0.5f);//在同一层次,再随机不同的深度位置,不至于重叠一起,显得错落有致


            Vector4 posTemp = newData[j].position;
            newData[j].position = new Vector4(posTemp.x, posTemp.y, posTemp.z, 1);

            Vector2 randomPoint;



            if (randomPos.Count > 0)
            {
                // Random.InitState(Random.Range(0, randomPos.Count));

                int rangIndex = Random.Range(0, randomPos.Count);

                randomPoint = randomPos[rangIndex];

                randomPos.RemoveAt(rangIndex);
            }
            else//如果多出来,则放到看不到的地方
            {
                randomPoint = new Vector2(_screenPosLeftDown.x, Random.Range(1000f, 2000f));
            }


            // Vector2 randomPoint = randomPos[j % randomPos.Count];

            //计算Y轴的位置(1 - scaleY)为空余的位置(1 - scaleY)/2f上下空余的位置,(1 - scaleY)/2f*(_screenPosLeftUp.y - _screenPosLeftDown.y)空余位置的距离
            float heightTmep = (1 - scaleY) / 2f * (_screenPosLeftUp.y - _screenPosLeftDown.y);

            randomPoint = new Vector2(randomPoint.x + _screenPosLeftDown.x, randomPoint.y + _screenPosLeftDown.y + heightTmep);

            newData[j].moveTarget = new Vector3(randomPoint.x, randomPoint.y + Common.HeightTemp, rangeZ);
            newData[j].uvOffset   = new Vector4(1f, 1f, 0f, 0f);
            newData[j].uv2Offset  = new Vector4(1f, 1f, 0f, 0f);

            int     picIndex = 0;
            Vector2 size     = PictureHandle.Instance.GetLevelIndexSize(j, k - 1, out picIndex);//得到缩放尺寸

            float xScale     = size.x / 512f;
            float yScale     = size.y / 512f;
            float proportion = size.x / size.y;
            if (xScale >= 2 || yScale >= 2)
            {
                //如果超过2倍大小,则强制缩放到一倍大小以内,并以宽度为准,等比例减少
                int a = (int)xScale;
                xScale = xScale - (a) + 2f;

                yScale = xScale / proportion;
            }


            newData[j].initialVelocity = new Vector3(xScale, yScale, 0f);//填充真实宽高
            newData[j].picIndex        = picIndex;

            newData[j].bigIndex = picIndex;
            //x存储层次的索引,y存储透明度,   z存储,x轴右边的边界值,为正数   ,最后一个为随机深度
            newData[j].velocity = new Vector4(k - 1, 1f, _screenPosRightDown.x * 4f, 0);
            Vector4 otherData = new Vector4();
            newData[j].originalPos = otherData;
        }
        TextureInstanced.Instance.ChangeInstanceMat(CurMaterial);
        CurMaterial.enableInstancing = true;

        TextureInstanced.Instance.CurMaterial.SetVector("_WHScale", new Vector4(1f, 1f, 1f, 1f));



        allDataList.AddRange(newData);

        ComputeBuffer.SetData(allDataList.ToArray());
        _depthBuffer.SetData(_depths);

        ComputeShader.SetBuffer(dispatchID, "depthBuffer", _depthBuffer);
        ComputeShader.SetBuffer(dispatchID, "positionBuffer", ComputeBuffer);

        ComputeShader.SetFloat("Width", Screen.width);
        ComputeShader.SetFloat("Height", Screen.height);

        Matrix4x4 camMatri = Camera.main.projectionMatrix;

        ComputeShader.SetFloat("m32", camMatri.m32);
        ComputeShader.SetFloat("m00", camMatri.m00);
        ComputeShader.SetFloat("m11", camMatri.m11);
        ComputeShader.SetVector("camPos", Camera.main.transform.position);



        // ComputeShader.SetFloats(dispatchID, "positionBuffer", ComputeBuffer);


        // _depthPictureMove = new MultiDepthPictureMove(newData,_depths,Canvas);

        //ComputeShader.SetBuffer(InitID, "positionBuffer", ComputeBuffer);
        //ComputeShader.SetBuffer(InitID, "depthBuffer", _depthBuffer);

        TextureInstanced.Instance.CurMaterial.SetBuffer("positionBuffer", ComputeBuffer);
        TextureInstanced.Instance.CurMaterial.SetTexture("_TexArr", TextureInstanced.Instance.TexArr);


        MoveSpeed = 50f;//更改更快的插值速度
        ComputeShader.SetFloat("MoveSpeed", MoveSpeed);
        ComputeShader.SetFloat("dis", 800);

        ComputeShader.SetBuffer(dispatchID, "clickPointsBuff", _clickPointBuff);


        //触摸点最大为十个
        List <Vector3> clicks = new List <Vector3>();

        for (int i = 0; i < 10; i++)
        {
            clicks.Add(Vector3.one * 100000);
        }
        _clickBuff = new ComputeBuffer(10, 12);
        _clickBuff.SetData(clicks.ToArray());
        ComputeShader.SetBuffer(dispatchID, "clicks", _clickBuff);
        InitDisPatch(InitID);
    }
    protected override void Dispatch(ComputeBuffer system)
    {
        // MouseButtonDownAction();

        Vector3[] temp = new Vector3[_clickBuff.count];

        //_clickBuff.GetData(temp);
        //传输过去前,先重置数据
        //
        for (int i = 0; i < temp.Length; i++)
        {
            temp[i] = Vector3.one * 1000000;
        }

        int n = 0;

        foreach (KeyValuePair <int, ClickData> keyValuePair in _touchIds)
        {
            Vector3 pos = keyValuePair.Value.Position;
            //Debug.Log(pos);
            // pos = Camera.main.ScreenToWorldPoint(new Vector3(pos.x, pos.y, 6));//6 深度是相机到物体的深度  是第一排物体的离相机的距离
            temp[n] = pos;
            n++;
        }

        LeftDownTip.position = temp[0];
        _clickBuff.SetData(temp);
        ComputeShader.SetBuffer(dispatchID, "clicks", _clickBuff);


        //if (Input.GetMouseButtonDown(1))
        //{
        //    ComputeShader.SetVector("rangeRot", new Vector4(_zeroIndexCount + 115, _zeroIndexCount + 130, _zeroIndexCount + 50, _zeroIndexCount + 157));
        //}
        //if (Input.GetMouseButtonUp(1))
        //{
        //    ComputeShader.SetVector("rangeRot", new Vector4(-1, -1, -1, -1));
        //}

        Ray ray;

        // Debug.Log(_clickPoint + "    " + Input.mousePosition);
        ray = Camera.main.ScreenPointToRay(_clickPoint);
        Vector3    clickPos = Vector3.one * 100000;
        RaycastHit hitInfo;

        if (Physics.Raycast(ray, out hitInfo))
        {
            clickPos = hitInfo.transform.position;
        }

        if (_clickPoint.z < 0)
        {
            _clickPoint = Camera.main.ScreenToWorldPoint(new Vector3(_clickPoint.x, _clickPoint.y, 6));
        }
        else
        {
            _clickPoint = Vector3.one * 1000000;
        }

        //_depthPictureMove.Excute(temp);


        ComputeShader.SetVector("clickPoint", _clickPoint);
        ComputeShader.SetFloat("deltaTime", Time.deltaTime);
        //Camera.main.ResetTransparencySortSettings();
        //Camera.main.transparencySortAxis = Vector3.right;
        //Camera.main.transparencySortMode = TransparencySortMode.CustomAxis;


        Dispatch(dispatchID, system);

        if (_clickPoint.z < 1000000)//相当于有点击事件才触发
        {
            PosAndDir[] datas = new PosAndDir[1];
            _clickPointBuff.GetData(datas);
            int     index = datas[0].picIndex;
            Vector3 temp1 = Camera.main.ScreenToWorldPoint(new Vector3(400, 500, 10));
            // Debug.Log("click WorldToScreenPos  is " + datas[0].moveDir + "     aip实现是 " + temp1);
            PictureHandle.Instance.GetYearInfo(datas[0], Canvas.transform);
            _clickPoint = Vector3.one * 1000000;//重置数据
        }
    }
示例#15
0
 public void WithDataExtracted(Action action)
 {
     data.GetData(managedData);
     action();
     data.SetData(managedData);
 }
示例#16
0
    //updating the terrain with compute shaders on the GPU
    public void UpdateTerrainGPU(Chunk chunk)
    {
        //create buffers for GPU call
        CreateBuffers();

        //int PointsPerAxis = VoxelsPerAxis + 1;
        float      voxelSpacing = ChunkSize / (float)VoxelsPerAxis;
        Vector3Int coord        = chunk.Pos;
        Vector3    chunkCentre  = GetChunkCentre(coord);
        //get world size
        Vector3 worldSize = new Vector3(NumOfChunks.x, NumOfChunks.y, NumOfChunks.z) * ChunkSize;

        //generate the noise
        noiseGenerator.Generate(voxelBuffer, VoxelsPerAxis, ChunkSize, worldSize, chunkCentre, voxelSpacing, noiseType);
        //generate the mesh points
        MarchingCubes.UpdateTerrainGPU(MarchingCubesCompute, voxelBuffer, triangleBuffer, VoxelsPerAxis, ISOValue);

        // Get number of triangles in the triangle buffer
        ComputeBuffer.CopyCount(triangleBuffer, triCountBuffer, 0);
        int[] triCountArray = { 0 };
        //update the mesh with the populated triangle buffer
        triCountBuffer.GetData(triCountArray);
        int numTris = triCountArray[0];

        // Get triangle data from shader
        Triangle[] tris = new Triangle[numTris];
        triangleBuffer.GetData(tris, 0, 0, numTris);

        //clear the buffers immediatly
        ReleaseBuffers();

        //clear the meash ready for update
        Mesh mesh = chunk.mesh;

        mesh.Clear();

        var vertices      = new Vector3[numTris * 3];
        var meshTriangles = new int[numTris * 3];

        //set verts & tris for mesh
        for (int i = 0; i < numTris; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                meshTriangles[i * 3 + j] = i * 3 + j;
                vertices[i * 3 + j]      = tris[i][j];
            }
        }
        mesh.vertices  = vertices;
        mesh.triangles = meshTriangles;

        //point everything in the right direction
        mesh.RecalculateNormals();

        //rerun the setup to recalc collisions if player is in that chunk
        //position of player
        Vector3 PlayerPos  = player.transform.position;
        float   PlayerBase = player.GetComponent <SphereCollider>().radius;
        //chunk player is in
        Vector3Int ChunkOccupied = Vector3Int.RoundToInt((PlayerPos - new Vector3(0, PlayerBase, 0)) / ChunkSize);

        //generate all collisions on start if fixed time
        if (FixedMapSize)
        {
            chunk.SetUp(GenerateCollisions, material);
        }
        else
        {
            //only generate collisions on the chunk the player is in
            //  (or directly above or below as this was causing mesh failures with the physics timing and player was falling through)
            bool GenCollisions = false;
            if (VectorEqu(ChunkOccupied, chunk.Pos, new Vector3(0, 1, 0)))
            {
                GenCollisions = true;
            }
            chunk.SetUp(GenCollisions, material);
        }


        //handle garbage collection when app stops running
        if (!Application.isPlaying)
        {
            ReleaseBuffers();
        }
    }
示例#17
0
    public static List <Vector4> GetClusters(List <Vector4> atoms, int numCentroids)
    {
        if (ComputeShaderManager.Instance.KMeansCS == null)
        {
            throw new Exception("KMeans compute shader not assigned");
        }

        if (numCentroids <= 0)
        {
            throw new Exception("Num centroids too low");
        }

        var centroids    = new List <Vector4>();
        var centroidStep = Mathf.CeilToInt(atoms.Count / (float)numCentroids);

        for (int i = 0; i < numCentroids; i++)
        {
            if (i * centroidStep < atoms.Count)
            {
                centroids.Add(atoms[i * centroidStep]);
            }
            else
            {
                centroids.Add(atoms[UnityEngine.Random.Range(0, atoms.Count)]);
            }
        }

        var centroidBuffer = new ComputeBuffer(numCentroids, 4 * sizeof(float));

        centroidBuffer.SetData(centroids.ToArray());

        var pointBuffer = new ComputeBuffer(atoms.Count, 4 * sizeof(float));

        pointBuffer.SetData(atoms.ToArray());

        var membershipBuffer = new ComputeBuffer(atoms.Count, sizeof(int));

        ComputeShaderManager.Instance.KMeansCS.SetInt("_NumPoints", atoms.Count);
        ComputeShaderManager.Instance.KMeansCS.SetInt("_NumCentroids", numCentroids);

        for (int i = 0; i < 5; i++)
        {
            ComputeShaderManager.Instance.KMeansCS.SetBuffer(0, "_PointBuffer", pointBuffer);
            ComputeShaderManager.Instance.KMeansCS.SetBuffer(0, "_CentroidBuffer", centroidBuffer);
            ComputeShaderManager.Instance.KMeansCS.SetBuffer(0, "_MembershipBuffer", membershipBuffer);
            ComputeShaderManager.Instance.KMeansCS.Dispatch(0, Mathf.CeilToInt(atoms.Count / 64.0f), 1, 1);

            ComputeShaderManager.Instance.KMeansCS.SetBuffer(1, "_PointBuffer", pointBuffer);
            ComputeShaderManager.Instance.KMeansCS.SetBuffer(1, "_NewCentroidBuffer", centroidBuffer);
            ComputeShaderManager.Instance.KMeansCS.SetBuffer(1, "_NewMembershipBuffer", membershipBuffer);
            ComputeShaderManager.Instance.KMeansCS.Dispatch(1, Mathf.CeilToInt(numCentroids / 64.0f), 1, 1);
        }

        var newCentroids = new Vector4[numCentroids];

        centroidBuffer.GetData(newCentroids);

        pointBuffer.Release();
        centroidBuffer.Release();
        membershipBuffer.Release();

        return(newCentroids.ToList());
    }
示例#18
0
    protected override void Init()
    {
        base.Init();



        _screenPosLeftDown  = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, Z - Camera.main.transform.position.z));
        _screenPosLeftUp    = Camera.main.ScreenToWorldPoint(new Vector3(0, Height, Z - Camera.main.transform.position.z));
        _screenPosRightDown = Camera.main.ScreenToWorldPoint(new Vector3(Width, 0, Z - Camera.main.transform.position.z));
        _screenPosRightUp   = Camera.main.ScreenToWorldPoint(new Vector3(Width, Height, Z - Camera.main.transform.position.z));

        int instanceCount = TextureInstanced.Instance.InstanceCount;

        PosAndDir[] datas = new PosAndDir[ComputeBuffer.count];

        ComputeBuffer.GetData(datas);


        //根据种类个数生成盒子,先手动完成,盒子分配,有时间在完善=>开发出自动分配均匀大小的盒子填满窗口
        //这里以生成8个盒子还展开


        List <Rect> rects = new List <Rect>();

        if (CategoryCount == 8)
        {
            //生成八个盒子,横列4个,竖列2个
            float width  = Width / 4f;  //480
            float height = Height / 2f; //540

            //x,y 为倍数
            Rect rect0 = new Rect(0f, 0f, width, height);
            Rect rect1 = new Rect(1f, 0f, width, height);
            Rect rect2 = new Rect(2f, 0f, width, height);
            Rect rect3 = new Rect(3f, 0f, width, height);
            Rect rect4 = new Rect(0f, 1f, width, height);
            Rect rect5 = new Rect(1f, 1f, width, height);
            Rect rect6 = new Rect(2f, 1f, width, height);
            Rect rect7 = new Rect(3f, 1f, width, height);
            rects.Add(rect0);
            rects.Add(rect1);
            rects.Add(rect2);
            rects.Add(rect3);
            rects.Add(rect4);
            rects.Add(rect5);
            rects.Add(rect6);
            rects.Add(rect7);
        }



        //每个盒子分配得到的面片个数
        int     count = instanceCount / (int)CategoryCount;//8192
        Vector2 scale = Vector2.zero;

        for (int i = 0; i < rects.Count; i++)
        {
            Rect  rect   = rects[i];
            float width  = rect.width;
            float height = rect.height;

            float fitedge = (Mathf.Sqrt((width * height * 1f) / count)); //适合的边长,

            int row = (int)(width / fitedge);                            //求得大概行横列的个数,即一横有多少个

            int column = (int)(height / fitedge);                        //求得竖列大概的个数,即一竖有多少个

            float smallWidth = width * 1f / row;                         //求得小矩形屏幕分辨率的宽

            float smallHeight = height * 1f / column;                    //求得小矩形屏幕分辨率的高,

            //求得小矩形的宽和高后,填满大矩形的个数跟每个盒子分配的面片个数不一致,
            //我们以求得的宽高后的盒子为准,多余的面片我们舍去
            //row*column 为实际上用到的quad个数

            //小矩形的宽高转化为世界宽度和高度,注意Z轴
            Vector3 origin = Camera.main.ScreenToWorldPoint(new Vector3(0f, 0f, Z - Camera.main.transform.position.z));
            //世界位置小矩形的宽
            Vector3 wpos = Camera.main.ScreenToWorldPoint(new Vector3(smallWidth, 0f, Z - Camera.main.transform.position.z));
            //世界位置小矩形的高
            Vector3 hpos = Camera.main.ScreenToWorldPoint(new Vector3(0f, smallHeight, Z - Camera.main.transform.position.z));

            //得到小矩形在世界坐标中应得到的宽度
            float wwidth = wpos.x - origin.x;
            //得到小矩形哎世界坐标中得到的高度
            float wheight = hpos.y - origin.y;

            //世界位置大矩形的宽的位置
            Vector3 widthBigpos = Camera.main.ScreenToWorldPoint(new Vector3(rect.width, 0f, Z - Camera.main.transform.position.z));
            //世界位置大矩形的高的位置
            Vector3 heightBigpos = Camera.main.ScreenToWorldPoint(new Vector3(0f, rect.height, Z - Camera.main.transform.position.z));

            //得到大矩形在世界坐标中应得到的宽度
            float wwidthBig = widthBigpos.x - origin.x;
            //得到大矩形哎世界坐标中得到的高度
            float wheightBig = heightBigpos.y - origin.y;

            //因为quad边长为1,对quab进行缩放加工,quad的位置的Z轴位置一定要正确
            // Quab.transform.localScale = new Vector3(wwidth, wheight, 1f);

            scale = new Vector2(wwidth, wheight);//把面片缩放倍数弹出去



            int actual = row * column;//实际有作用的粒子个数

            //进一步加工uv  y=>rows  x=>horizontalColumn
            //得到一个新的uvwz,
            float u = 1f / row;

            float v = 1f / column;

            float delay = Random.Range(3, 8);



            //把小矩形填充整个大矩形
            int columnTempCount = 0;//横列个数    y轴概念
            for (int j = 0; j < actual; j++)
            {
                int index = i * count + j;//buff数组中的索引位置

                // Vector3 pos = Vector3.zero;
                if (j != 0 && j % row == 0)
                {
                    columnTempCount++;
                }
                int rowTempCount = j - columnTempCount * row;//竖列个数  x轴概念

                Vector3 pos = new Vector3(origin.x, origin.y, 0) +
                              //这里的xy,存放的是倍数
                              new Vector3(wwidthBig * rect.position.x, wheightBig * rect.position.y, 0) +
                              new Vector3(wwidth * rowTempCount + wwidth / 2, wheight * columnTempCount + wheight / 2f, Z);
                datas[index].moveTarget  = pos;
                datas[index].originalPos = Vector4.one;
                // datas[index].position = Vector4.one;
                datas[index].indexRC  = new Vector2(rowTempCount, columnTempCount);
                datas[index].picIndex = i;
                datas[index].bigIndex = i;                   //分类编号

                Vector4 otherData = new Vector4();           //切换图片索要缓存的数据
                otherData.x                  = delay;        //延迟播放的时间
                otherData.y                  = 1f;           //Random.Range(0.1f,1f);//切换图片的时间
                otherData.z                  = 0f;           //时间缓存
                otherData.w                  = 0f;           //插值值
                datas[index].velocity        = otherData;
                datas[index].initialVelocity = Vector3.zero; //缓存器
                float w = u * rowTempCount;                  //rowsCount

                float z = v * columnTempCount;               //columnCount

                datas[index].uvOffset = new Vector4(u, v, w, z);

                #region 设置第二套UV,写死规定每个小矩形在切分成九个小矩形,这里只设置UV切分



                float row2    = row / 3f;    //小小矩形的横轴个数
                float column2 = column / 3f; //小小矩形竖轴个数

                float u2 = 1f / row2;
                float v2 = 1f / column2;

                int indexrow    = (int)(rowTempCount * 1f / row2) + 1;       //小矩形里小小矩形的x轴个数
                int indexColumn = (int)(columnTempCount * 1f / column2) + 1; //小矩形里小小矩形的y轴的个数


                float w2 = ((rowTempCount % row2) * 1f / row2);

                float z2 = ((columnTempCount % column2) * 1f / column2);

                datas[index].uv2Offset = new Vector4(u2, v2, w2, z2);
                datas[index].bigIndex  = i + (indexColumn - 1) * 3 + indexrow;//分类编号*3是因为一横有三个
                #endregion
            }
            int useless = count - actual;//剩下的没有用到的面片,

            //全部缩小至0,位置也归零
            for (int j = 0; j < useless; j++)
            {
                int index = actual + j;

                datas[index].position = Vector4.zero;
                //datas[index].moveTarget = Vector3.zero;
                //datas[index].originalPos = Vector4.zero;
            }
        }
        TextureInstanced.Instance.ChangeInstanceMat(null);
        TextureInstanced.Instance.CurMaterial.SetVector("_WHScale", new Vector4(scale.x, scale.y, 1, 1));

        ComputeBuffer.SetData(datas);
        ComputeShader.SetBuffer(dispatchID, "positionBuffer", ComputeBuffer);
        ComputeShader.SetBuffer(InitID, "positionBuffer", ComputeBuffer);
        MoveSpeed = 50f;//更改更快的插值速度
        ComputeShader.SetFloat("MoveSpeed", MoveSpeed);
    }
    public static void ICP_iteration(Vector3[] startPoints, Vector3[] stopPoints, out Quaternion Qe, out Vector3 Te, out Vector3[] projectedStopPoints, out int[] match_idx_array)
    {
        //Debug.Log("ICP iteration!");
        int N = startPoints.Length;

        if (stopPoints.Length != N)
        {
            Debug.Log("ICP ITERATION CANT WORK BECAUSE START POINT LENGHT AND STOP POINT LENGTH ARE NOT THE SAME");
        }


        Qe = Quaternion.identity;
        Te = new Vector3();
        projectedStopPoints = new Vector3[stopPoints.Length];

        ComputeBuffer start_point_buffer = new ComputeBuffer(startPoints.Length, 3 * sizeof(float));
        ComputeBuffer stop_point_buffer  = new ComputeBuffer(stopPoints.Length, 3 * sizeof(float));

        start_point_buffer.SetData(startPoints);
        stop_point_buffer.SetData(stopPoints);

        int matchImage_kh = icp_shader.FindKernel("matchImage");

        icp_shader.SetBuffer(matchImage_kh, "start_point_buffer", start_point_buffer);
        icp_shader.SetBuffer(matchImage_kh, "stop_point_buffer", stop_point_buffer);
        icp_shader.SetFloat("result_scale", result_scale);


        if (rt == null || rt.width != N || rt.width != N)
        {
            rt = new RenderTexture(N, N, 24, RenderTextureFormat.ARGBFloat);
            rt.enableRandomWrite = true;
            rt.filterMode        = FilterMode.Point;
            rt.Create();
        }

        icp_shader.SetTexture(matchImage_kh, "match_tex", rt);

        icp_shader.Dispatch(matchImage_kh, ((int)(N / 8)) + 1, ((int)(N / 8)) + 1, 1);

        debugCube.GetComponent <Renderer>().material             = new Material(Shader.Find("Unlit/Texture"));
        debugCube.GetComponent <Renderer>().material.mainTexture = rt;



        //match points using matchImage:
        int           matchPoints_kh   = icp_shader.FindKernel("matchPoints");
        ComputeBuffer match_idx_buffer = new ComputeBuffer(startPoints.Length, sizeof(int));

        icp_shader.SetBuffer(matchPoints_kh, "start_point_buffer", start_point_buffer);
        icp_shader.SetBuffer(matchPoints_kh, "stop_point_buffer", stop_point_buffer);
        icp_shader.SetBuffer(matchPoints_kh, "match_idx_buffer", match_idx_buffer);
        icp_shader.SetTexture(matchPoints_kh, "match_tex", rt);
        icp_shader.SetFloat("neighbor_threshold", neighbor_threshold);
        icp_shader.SetInt("num_points", startPoints.Length);

        icp_shader.Dispatch(matchPoints_kh, (startPoints.Length / 64) + 1, 1, 1);

        match_idx_array = new int[startPoints.Length];
        match_idx_buffer.GetData(match_idx_array);

        List <Vector3> startMatchList = new List <Vector3>();
        List <Vector3> stopMatchList  = new List <Vector3>();
        List <Vector2> matchIdxList   = new List <Vector2>();

        for (int i = 0; i < startPoints.Length; i++)
        {
            if (match_idx_array[i] >= 0)
            {
                startMatchList.Add(startPoints[i]);
                stopMatchList.Add(stopPoints[match_idx_array[i]]);
                matchIdxList.Add(new Vector2(i, match_idx_array[i]));
            }
        }

        /*
         * Debug.Log("Found Neighbor matches: " + startMatchList.Count);
         * for(int i = 0; i<startMatchList.Count; i++)
         * {
         *  Debug.Log("Point " + i + ": dist: " + (startMatchList[i] - stopMatchList[i]).magnitude + " midx: " + matchIdxList[i] + " p1: " + startMatchList[i] + " p2: " + stopMatchList[i]);
         * }
         */

        if (ICP.in_plane_only)
        {
            estimateInPlaneTransform(startMatchList.ToArray(), stopMatchList.ToArray(), out Qe, out Te);
        }
        else
        {
            estimateTransform(startMatchList.ToArray(), stopMatchList.ToArray(), out Qe, out Te);
        }



        //Debug.Log("estimated Q: " + Qe + " Estimated Te: " + Te);

        //reproject stop points:
        Matrix4x4 projection = Matrix4x4.TRS(Te, Qe, new Vector3(1.0f, 1.0f, 1.0f));
        //projection = Matrix4x4.TRS(new Vector3(0.0f, 0.5f, 0.0f), Quaternion.identity, new Vector3(1.0f, 1.0f, 1.0f));
        //Debug.Log("projection matrix: " + projection);

        int           projectPoints_kh = icp_shader.FindKernel("projectPoints");
        ComputeBuffer reprojected_stop_point_buffer = new ComputeBuffer(stopPoints.Length, 3 * sizeof(float));

        icp_shader.SetBuffer(projectPoints_kh, "stop_point_buffer", stop_point_buffer);
        icp_shader.SetBuffer(projectPoints_kh, "reprojected_stop_point_buffer", reprojected_stop_point_buffer);
        icp_shader.SetMatrix("matFromStopToStart", projection.inverse);

        icp_shader.Dispatch(projectPoints_kh, (stopPoints.Length / 64) + 1, 1, 1);

        reprojected_stop_point_buffer.GetData(projectedStopPoints);

        start_point_buffer.Dispose();
        stop_point_buffer.Dispose();
        reprojected_stop_point_buffer.Dispose();
        match_idx_buffer.Dispose();
    }
示例#20
0
    /// <summary>
    /// 改变状态,直接把大矩形填满整个屏幕,其他大矩形则透明掉
    /// </summary>
    public void ChangeState(int classNumber)
    {
        if (Type != MotionType.ClassiFicationMotion)
        {
            return;
        }

        PosAndDir[] datas = new PosAndDir[ComputeBuffer.count];

        ComputeBuffer.GetData(datas);
        List <PosAndDir> temp        = new List <PosAndDir>();
        List <PosAndDir> allDataList = new List <PosAndDir>();

        //这里注意,posAndDir属于结构体,值拷贝
        for (int i = datas.Length - 1; i >= 0; i--)
        {
            PosAndDir data = datas[i];
            if (datas[i].bigIndex == classNumber)
            {
                temp.Add(data);//编号一样的单独拿出来
            }
            else
            {
                data.position = Vector4.zero;//其他编号都隐藏
                allDataList.Add(data);
            }
        }

        PosAndDir[] newData = temp.ToArray();

        //根据分辨率展开图片 写死每个大矩形的宽高
        int widthCount  = Width / 96;   //每个图片宽99像素
        int heightCount = Height / 108; //每个图片高108素


        List <Rect> rects = new List <Rect>();

        int tempHeithtCount = 0;//y轴上的个数

        for (int i = 0; i < widthCount * heightCount; i++)
        {
            if (i != 0 && i % widthCount == 0)
            {
                tempHeithtCount++;
            }
            int tempWidthCount = i - tempHeithtCount * widthCount;//轴上的个数

            Rect rect = new Rect(tempWidthCount, tempHeithtCount, 96f, 108f);
            rects.Add(rect);
        }

        //每个盒子分配得到的面片个数 会有概率盒子分配过剩,记得把过剩的处理
        int     count = newData.Length / rects.Count;
        Vector2 scale = Vector2.zero;

        for (int i = 0; i < rects.Count; i++)
        {
            #region 处理小矩形
            Rect  rect   = rects[i];
            float width  = rect.width;
            float height = rect.height;

            float fitedge = (Mathf.Sqrt((width * height * 1f) / count)); //适合的边长,

            int row = (int)(width / fitedge);                            //求得大概行横列的个数,即一横有多少个

            int column = (int)(height / fitedge);                        //求得竖列大概的个数,即一竖有多少个

            float smallWidth = width * 1f / row;                         //求得小矩形屏幕分辨率的宽

            float smallHeight = height * 1f / column;                    //求得小矩形屏幕分辨率的高,

            //求得小矩形的宽和高后,填满大矩形的个数跟每个盒子分配的面片个数不一致,
            //我们以求得的宽高后的盒子为准,多余的面片我们舍去
            //row*column 为实际上用到的quad个数

            //小矩形的宽高转化为世界宽度和高度,注意Z轴
            Vector3 origin = Camera.main.ScreenToWorldPoint(new Vector3(0f, 0f, Z - Camera.main.transform.position.z));
            //世界位置小矩形的宽
            Vector3 wpos = Camera.main.ScreenToWorldPoint(new Vector3(smallWidth, 0f, Z - Camera.main.transform.position.z));
            //世界位置小矩形的高
            Vector3 hpos = Camera.main.ScreenToWorldPoint(new Vector3(0f, smallHeight, Z - Camera.main.transform.position.z));

            //得到小矩形在世界坐标中应得到的宽度
            float wwidth = wpos.x - origin.x;
            //得到小矩形哎世界坐标中得到的高度
            float wheight = hpos.y - origin.y;

            //世界位置大矩形的宽的位置
            Vector3 widthBigpos = Camera.main.ScreenToWorldPoint(new Vector3(rect.width, 0f, Z - Camera.main.transform.position.z));
            //世界位置大矩形的高的位置
            Vector3 heightBigpos = Camera.main.ScreenToWorldPoint(new Vector3(0f, rect.height, Z - Camera.main.transform.position.z));

            //得到大矩形在世界坐标中应得到的宽度
            float wwidthBig = widthBigpos.x - origin.x;
            //得到大矩形哎世界坐标中得到的高度
            float wheightBig = heightBigpos.y - origin.y;

            //因为quad边长为1,对quab进行缩放加工,quad的位置的Z轴位置一定要正确
            // Quab.transform.localScale = new Vector3(wwidth, wheight, 1f);

            scale = new Vector2(wwidth, wheight);//把面片缩放倍数弹出去



            int actual = row * column;//实际有作用的粒子个数

            //进一步加工uv  y=>rows  x=>horizontalColumn
            //得到一个新的uvwz,
            float u = 1f / row;

            float v = 1f / column;

            float delay = Random.Range(3, 8);



            //把小矩形填充整个大矩形
            int rowsCount = 0;//横列个数    y轴概念
            for (int j = 0; j < count; j++)
            {
                int index = i * count + j;//buff数组中的索引位置


                if (j >= actual)//多余的面片不应该显示
                {
                    newData[index].position = Vector4.zero;
                    //newData[index].moveTarget = Vector3.zero;
                    //newData[index].originalPos = Vector4.zero;

                    continue;
                }

                // Vector3 pos = Vector3.zero;
                if (j != 0 && j % row == 0)
                {
                    rowsCount++;
                }
                int columnCount = j - rowsCount * row;//竖列个数  x轴概念

                Vector3 pos = new Vector3(origin.x, origin.y, 0) +
                              //这里的xy,存放的是倍数
                              new Vector3(wwidthBig * rect.position.x, wheightBig * rect.position.y, 0) +
                              new Vector3(wwidth * columnCount + wwidth / 2, wheight * rowsCount + wheight / 2f, Z);


                newData[index].moveTarget  = pos;
                newData[index].originalPos = Vector4.one;
                newData[index].indexRC     = new Vector2(columnCount, rowsCount);
                newData[index].picIndex    = i % TextureInstanced.Instance.TexArr.depth;
                newData[index].bigIndex    = i % TextureInstanced.Instance.TexArr.depth; //分类编号

                Vector4 otherData = new Vector4();                                       //切换图片索要缓存的数据
                otherData.x             = delay;                                         //延迟播放的时间
                otherData.y             = 1f;                                            //Random.Range(0.1f,1f);//切换图片的时间
                otherData.z             = 0f;                                            //时间缓存
                otherData.w             = 0f;                                            //插值值
                newData[index].velocity = otherData;


                float w = u * columnCount;

                float z = v * rowsCount;//rowsCount

                newData[index].uvOffset  = new Vector4(u, v, w, z);
                newData[index].uv2Offset = new Vector4(u, v, w, z);
            }
            #endregion
        }

        //计算剩余的不用的面片隐藏掉
        int surplusCount = newData.Length - count * rects.Count;

        if (surplusCount > 0)
        {
            for (int i = newData.Length - 1; i >= newData.Length - surplusCount; i--)
            {
                newData[i].position = Vector4.zero;
            }
        }

        TextureInstanced.Instance.CurMaterial.SetVector("_WHScale", new Vector4(scale.x, scale.y, 1, 1));


        allDataList.AddRange(newData);

        ComputeBuffer.SetData(allDataList.ToArray());
        ComputeShader.SetBuffer(dispatchID, "positionBuffer", ComputeBuffer);
        ComputeShader.SetBuffer(InitID, "positionBuffer", ComputeBuffer);
        MoveSpeed = 50f;//更改更快的插值速度
        ComputeShader.SetFloat("MoveSpeed", MoveSpeed);

        InitDisPatch(InitID);
    }
示例#21
0
    public void DetectBlobs()
    {
        var kernel = cclCompute.FindKernel("init");

        cclCompute.SetTexture(kernel, "inTex", inputTex);
        cclCompute.SetTexture(kernel, "labelTex", labelTex);
        cclCompute.SetInt("numMaxLabel", numMaxLabels);
        cclCompute.SetInt("texWidth", width);
        cclCompute.SetInt("texHeight", height);
        cclCompute.Dispatch(kernel, width / 8, height / 8, 1);

        kernel = cclCompute.FindKernel("columnWiseLabel");
        cclCompute.SetTexture(kernel, "labelTex", labelTex);
        cclCompute.Dispatch(kernel, width / 8, 1, 1);

        var itr = Mathf.Log(width, 2);
        var div = 2;

        for (var i = 0; i < itr; i++)
        {
            kernel = cclCompute.FindKernel("mergeLabels");
            cclCompute.SetTexture(kernel, "labelTex", labelTex);
            cclCompute.SetInt("div", div);

            cclCompute.Dispatch(kernel, Mathf.Max(width / (2 << i) / 8, 1), 1, 1);
            div *= 2;
        }

        kernel = cclCompute.FindKernel("clearLabelFlag");
        cclCompute.SetTexture(kernel, "labelTex", labelTex);
        cclCompute.SetBuffer(kernel, "labelBuffer", labelAppendBuffer);
        cclCompute.SetBuffer(kernel, "labelFlg", labelFlgBuffer);
        cclCompute.Dispatch(kernel, width * height / 8, 1, 1);

        kernel = cclCompute.FindKernel("setRootLabel");
        cclCompute.SetTexture(kernel, "labelTex", labelTex);
        cclCompute.SetBuffer(kernel, "labelFlg", labelFlgBuffer);
        cclCompute.Dispatch(kernel, width / 8, height / 8, 1);

        labelAppendBuffer.SetCounterValue(0);
        kernel = cclCompute.FindKernel("countLabel");
        cclCompute.SetBuffer(kernel, "labelFlg", labelFlgBuffer);
        cclCompute.SetBuffer(kernel, "labelAppend", labelAppendBuffer);
        cclCompute.Dispatch(kernel, width * height / 8, 1, 1);

        kernel = cclCompute.FindKernel("clearLabelData");
        cclCompute.SetBuffer(kernel, "labelDataBuffer", labelDataBuffer);
        cclCompute.Dispatch(kernel, numPerLabel * numMaxLabels / 8, 1, 1);

        for (var i = 0; i < numMaxLabels; i++)
        {
            cclCompute.SetInt("labelIdx", i);
            cclCompute.SetInt("numPerLabel", numPerLabel);

            labelDataAppendBuffer.SetCounterValue(0);
            kernel = cclCompute.FindKernel("clearLabelData");
            cclCompute.SetBuffer(kernel, "labelDataBuffer", labelDataAppendBuffer);
            cclCompute.Dispatch(kernel, numPerLabel / 8, 1, 1);

            kernel = cclCompute.FindKernel("appendLabelData");
            cclCompute.SetBuffer(kernel, "labelBuffer", labelAppendBuffer);
            cclCompute.SetTexture(kernel, "labelTex", labelTex);
            cclCompute.SetBuffer(kernel, "labelDataAppend", labelDataAppendBuffer);
            cclCompute.Dispatch(kernel, width / 8, height / 8, 1);

            kernel = cclCompute.FindKernel("setLabelData");
            cclCompute.SetBuffer(kernel, "inLabelDataBuffer", labelDataAppendBuffer);
            cclCompute.SetBuffer(kernel, "labelDataBuffer", labelDataBuffer);
            cclCompute.Dispatch(kernel, numPerLabel / 8, 1, 1);
        }

        kernel = cclCompute.FindKernel("buildBlobData");
        cclCompute.SetBuffer(kernel, "inLabelDataBuffer", labelDataBuffer);
        cclCompute.SetBuffer(kernel, "labelDataBuffer", accumeLabelDataBuffer);
        cclCompute.Dispatch(kernel, 1, numMaxLabels, 1);

        ComputeBuffer.CopyCount(labelAppendBuffer, labelArgBuffer, sizeof(uint));
        labelArgBuffer.GetData(args);
        accumeLabelDataBuffer.GetData(labelData);
    }
示例#22
0
    void Update()
    {
        if (!isRunningTask)
        {
            if (!EditorApplication.isPlaying && animation != null)
            {
                animation["BitAnimator.RuntimeAnimation"].time = audio.time;
                animation.Sample();
            }
            if (!isRunningTask && !EditorApplication.isPaused && target != null && target.core != null && target.recordSlots.Count > 0 && animation != null && audio != null)
            {
                target.animationTime = audio.time;

                if (texture == null)
                {
                    texture = new RenderTexture(512, 256, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
                    texture.enableRandomWrite = true;
                    texture.Create();
                    target.core.texture = texture;
                }
                BitAnimator.RecordSlot slot = target.recordSlots[selectedSlot];
                BitAnimator.SetMode(ref mode, target.calculateLoudness, target.energyCorrection);
                target.core.mode          = mode;
                target.core.resolveFactor = target.deconvolution;
                target.core.SetRemap(slot.remap);
                float         mul        = autoMultiply * multiply;
                ComputeBuffer viewValues = null;
                switch (plotGraphic)
                {
                case PlotGraphic.Histogram:
                    viewValues = target.core.RenderHistogram(
                        texture,
                        audio.time,
                        mul,
                        slot.startFreq,
                        slot.endFreq,
                        slot.ampSmoothness,
                        smoothFrequency);
                    break;

                case PlotGraphic.Peaks:
                    viewValues = target.core.RenderPeaks(
                        texture,
                        audio.time,
                        scale,
                        mul,
                        slot.startFreq,
                        slot.endFreq,
                        slot.ampSmoothness,
                        smoothFrequency,
                        slot.damping);
                    break;

                case PlotGraphic.Spectrum:
                    viewValues = target.core.RenderSpectrum(
                        texture,
                        audio.time,
                        scale,
                        mul,
                        slot.startFreq,
                        slot.endFreq,
                        slot.ampSmoothness,
                        smoothFrequency);
                    break;

                    /*case PlotGraphic.Tones:
                     *  target.core.RenderMainTone(
                     *      texture,
                     *      audio.time,
                     *      scale,
                     *      mul,
                     *      slot.ampSmoothness,
                     *      smoothFrequency);
                     *  break;
                     * case PlotGraphic.Wave:
                     *  rms = target.core.RenderWave(texture, audio.time, 2.0f, mul, slot.ampSmoothness, smoothFrequency); break;*/
                }
                if (viewValues != null)
                {
                    float[] values = new float[target.core.spectrumChunks];
                    viewValues.GetData(values);
                    Array.Sort(values);
                    median  = values[target.core.spectrumChunks / 2];
                    maximum = Math.Max(0.00001f, values[target.core.spectrumChunks - 1]);
                    rms     = target.core.GetRMS(values);
                    if (resetInNextFrame)
                    {
                        if (float.IsInfinity(multiply) || float.IsNaN(multiply))
                        {
                            multiply = 1.0f;
                        }
                        if (float.IsInfinity(autoMultiply) || float.IsNaN(autoMultiply))
                        {
                            autoMultiply = 1.0f;
                        }
                        if (float.IsInfinity(maximum) || float.IsNaN(maximum))
                        {
                            maximum = 1.0f;
                        }
                        autoMultiply     = 0.95f / (maximum / autoMultiply / multiply);
                        resetInNextFrame = false;
                    }
                    if (audio.isPlaying && (mode & ComputeProgram.VisualizationMode.RuntimeNormalize) != 0)
                    {
                        float delta = 0.95f / (maximum / autoMultiply / multiply) - autoMultiply;
                        if (delta < 0)
                        {
                            float k = 1.0f - Mathf.Exp(-Time.deltaTime * autoNormilizeSpeed);
                            autoMultiply += k * delta;
                        }
                    }
                }
                Repaint();
            }
        }
    }
    IEnumerator SetupParticles()
    {
        calculating = true;
        lck         = new object();
        maxRange    = Mathf.NegativeInfinity;

        if (anim != null)
        {
            StopCoroutine(anim);
        }

        int totalFrames           = 30;
        int defaultParticlesPerES = particleCount / expressionSets.Count;
        //number of frames used for each expression set.
        int framesPerES = totalFrames / expressionSets.Count;

        num_threads = SystemInfo.processorCount;
        int missingParticles = 0;

        threadResults = new List <Particle[]>();

        int expressionNumber = 0;

        foreach (ExpressionSet es in expressionSets)
        {
            particlesPerES   = defaultParticlesPerES + missingParticles;
            missingParticles = 0;
            expressionNumber++;
            //soft copy of the expressionSet. Do not edit actual expressions using this.
            ExpressionSet expressionSet = es.ShallowCopy();
            //remove unused parameters
            string[] keys = new string[expressionSet.ranges.Keys.Count];
            expressionSet.ranges.Keys.CopyTo(keys, 0);
            foreach (string op in keys)
            {
                bool used = false;
                foreach (ExpressionSet.ExpOptions key in expressionSet.expressions.Keys)
                {
                    if (expressionSet.expressions[key].tokens.Contains(op))
                    {
                        used = true;
                    }
                }
                if (!used && expressionSet.ranges.Count > 1)
                {
                    expressionSet.RemoveRange(op);
                }
            }

            int          depth        = expressionSet.ranges.Count;
            int          width        = (int)Mathf.Pow(particlesPerES, 1f / (float)depth);
            List <int[]> samples      = SetupSamples(depth, width);
            int          thread_chunk = Mathf.CeilToInt(samples.Count / 4);
            missingParticles += particlesPerES - samples.Count;

            Thread[] threads = new Thread[num_threads];
            int      t       = 0;
            for (t = 0; t < num_threads; t++)
            {
                int tc   = t;
                int TIDc = tc;


                threads[t] = new Thread(() => ThreadedEvaluate(samples.GetRange(tc * thread_chunk, Math.Min(thread_chunk, samples.Count - tc * thread_chunk)), expressionSet, TIDc));
                threads[t].Start();
            }
            while (framesPerES-- != 0)
            {
                yield return(null);
            }
            for (t = 0; t < num_threads; t++)
            {
                threads[t].Join();
            }
            framesPerES = totalFrames / expressionSets.Count;
        }
        List <Particle> temp = new List <Particle>();

        foreach (Particle[] array in threadResults)
        {
            temp.AddRange(array);
        }
        Particle lastParticle = temp[temp.Count - 1];

        for (int i = 0; i < missingParticles; i++)
        {
            temp.Add(lastParticle);
        }
        dest = temp.ToArray();
        for (int i = 0; i < dest.Length; i++)
        {
            Vector3 pos = (maxRange == 0) ? Vector3.zero : dest[i].position * 10f / maxRange;
            dest[i].position = pos;
            dest[i].color    = new Color(Mathf.Pow((pos.x + 10) / 20, 2), Mathf.Pow((pos.y + 10) / 20, 2), Mathf.Pow((pos.z + 10) / 20, 2));
        }

        xAxis.Max = maxRange; xAxis.Min = -maxRange;
        yAxis.Max = maxRange; yAxis.Min = -maxRange;
        zAxis.Max = maxRange; zAxis.Min = -maxRange;

        currentScale = (maxRange == 0) ? 0 : 10 / maxRange;

        pBuffer.GetData(particles);
        sBuffer.SetData(particles);
        dBuffer.SetData(dest);
        animProgress = 0;
        calculating  = false;
    }
示例#24
0
    void OnSceneGUI(SceneView sceneView)
    {
        if (Selection.activeGameObject == null)
        {
            return;
        }

        var gameobject = Selection.activeGameObject;

        Mesh mesh = null;

        var renderer = gameobject.GetComponent <MeshFilter>();

        if (renderer != null)
        {
            mesh = renderer.sharedMesh;
        }

        var skinnedrenderer = gameobject.GetComponent <SkinnedMeshRenderer>();

        if (skinnedrenderer != null)
        {
            mesh = skinnedrenderer.sharedMesh;
        }

        if (mesh == null)
        {
            return;
        }

        var transform = gameobject.transform.localToWorldMatrix;

        gpu_vertices.SetData(mesh.vertices);
        gpu_normals.SetData(mesh.normals);
        gpu_colours.SetData(mesh.colors);

        pointMaterial.SetBuffer("points", gpu_vertices);
        pointMaterial.SetBuffer("normals", gpu_normals);
        pointMaterial.SetBuffer("colours", gpu_colours);
        //pointMaterial.SetBuffer("flags", gpu_flags); //must use SetRandomWriteTarget instead.
        Graphics.SetRandomWriteTarget(1, gpu_flags, true);

        pointMaterial.SetMatrix("ObjectToWorld", transform);

        pointMaterial.SetFloat("Size", size);

        var mousePosition = Event.current.mousePosition;

        mousePosition.y = sceneView.camera.pixelHeight - mousePosition.y;
        var tool = new Vector4(mousePosition.x, mousePosition.y, brushSize, painting ? 1 : -1);

        pointMaterial.SetVector("Tool", tool);

        pointMaterial.SetInt("CullBackfacing", cullBackfacing ? 1 : 0);

        pointMaterial.SetPass(0);
        Graphics.DrawProcedural(MeshTopology.Points, mesh.vertexCount);

        Handles.BeginGUI();

        if (mouseOverWindow is SceneView)
        {
            if (Event.current.type == EventType.Repaint)
            {
                DrawCircleBrush(Color.white, brushSize);
            }
        }

        Handles.EndGUI();

        int controlid = GUIUtility.GetControlID(FocusType.Passive);

        if (Event.current.button == 0)
        {
            switch (Event.current.type)
            {
            case EventType.MouseDown:
            case EventType.MouseDrag:

                gpu_flags.GetData(cpu_flags);
                for (int i = 0; i < mesh.vertexCount; i++)
                {
                    if (((Flags)cpu_flags[i] & Flags.Selected) > 0)
                    {
                        selected.Add(i);
                    }
                }

                GUIUtility.hotControl = controlid;
                Event.current.Use();

                break;
            }
        }

        sceneView.Repaint();
    }
示例#25
0
    private Texture3D ComputeSDF()
    {
        // Create the voxel texture.
        Texture3D voxels = new Texture3D(resolution, resolution, resolution, TextureFormat.RGBAHalf, false);

        voxels.anisoLevel = 1;
        voxels.filterMode = FilterMode.Trilinear;
        voxels.wrapMode   = TextureWrapMode.Clamp;

        // Get an array of pixels from the voxel texture, create a buffer to
        // hold them, and upload the pixels to the buffer.
        Color[]       pixelArray  = voxels.GetPixels(0);
        ComputeBuffer pixelBuffer = new ComputeBuffer(pixelArray.Length, sizeof(float) * 4);

        pixelBuffer.SetData(pixelArray);

        // Get an array of triangles from the mesh.
        Vector3[]  meshVertices  = mesh.vertices;
        int[]      meshTriangles = mesh.GetTriangles(subMeshIndex);
        Triangle[] triangleArray = new Triangle[meshTriangles.Length / 3];
        for (int t = 0; t < triangleArray.Length; t++)
        {
            triangleArray[t].a = meshVertices[meshTriangles[3 * t + 0]];  // - mesh.bounds.center;
            triangleArray[t].b = meshVertices[meshTriangles[3 * t + 1]];  // - mesh.bounds.center;
            triangleArray[t].c = meshVertices[meshTriangles[3 * t + 2]];  // - mesh.bounds.center;
        }

        // Create a buffer to hold the triangles, and upload them to the buffer.
        ComputeBuffer triangleBuffer = new ComputeBuffer(triangleArray.Length, sizeof(float) * 3 * 3);

        triangleBuffer.SetData(triangleArray);

        // Instantiate the compute shader from resources.
        // ComputeShader compute = (ComputeShader)Instantiate(Resources.Load("SDF"));

        ComputeShader compute = AssetDatabase.LoadAssetAtPath <ComputeShader>("Assets/shaders/SDF.compute");
        int           kernel  = compute.FindKernel("CSMain");

        // Upload the pixel buffer to the GPU.
        compute.SetBuffer(kernel, "pixelBuffer", pixelBuffer);
        compute.SetInt("pixelBufferSize", pixelArray.Length);

        // Upload the triangle buffer to the GPU.
        compute.SetBuffer(kernel, "triangleBuffer", triangleBuffer);
        compute.SetInt("triangleBufferSize", triangleArray.Length);

        // Calculate and upload the other necessary parameters.
        compute.SetInt("textureSize", resolution);
        Vector3 minExtents = Vector3.zero;
        Vector3 maxExtents = Vector3.zero;

        foreach (Vector3 v in mesh.vertices)
        {
            for (int i = 0; i < 3; i++)
            {
                minExtents[i] = Mathf.Min(minExtents[i], v[i]);
                maxExtents[i] = Mathf.Max(maxExtents[i], v[i]);
            }
        }
        compute.SetVector("minExtents", minExtents - Vector3.one * padding);
        compute.SetVector("maxExtents", maxExtents + Vector3.one * padding);
        Debug.Log("Extents : " + (minExtents - Vector3.one * padding).ToString() + "~" + (maxExtents + Vector3.one * padding).ToString());
        // Debug.Log(minExtents - Vector3.one*padding);
        // Debug.Log(maxExtents + Vector3.one*padding);

        // Compute the SDF.
        compute.Dispatch(kernel, pixelArray.Length / 256 + 1, 1, 1);

        // Destroy the compute shader and release the triangle buffer.
        // DestroyImmediate(compute);
        triangleBuffer.Release();

        // Retrieve the pixel buffer and reapply it to the voxels texture.
        pixelBuffer.GetData(pixelArray);
        pixelBuffer.Release();
        voxels.SetPixels(pixelArray, 0);
        voxels.Apply();

        // Return the voxels texture.
        return(voxels);
    }
示例#26
0
    public void UpdateChunkMesh(Chunk chunk, bool?blocking = null)
    {
        int   numVoxelsPerAxis  = numPointsPerAxis - 1;
        int   numThreadsPerAxis = Mathf.CeilToInt(numVoxelsPerAxis / (float)threadGroupSize);
        float pointSpacing      = boundsSize / (numPointsPerAxis - 1);

        bool blockGpu = blocking ?? blockingGpu;

        Vector3Int coord  = chunk.coord;
        Vector3    centre = CentreFromCoord(coord);

        Vector3 worldBounds = new Vector3(numChunks.x, numChunks.y, numChunks.z) * boundsSize;

        densityGenerator.Generate(pointsBuffer, numPointsPerAxis, boundsSize, worldBounds, centre, offset, pointSpacing);

        void SetupShader()
        {
            triangleBuffer.SetCounterValue(0);
            shader.SetBuffer(0, "points", pointsBuffer);
            shader.SetBuffer(0, "triangles", triangleBuffer);
            shader.SetInt("numPointsPerAxis", numPointsPerAxis);
            shader.SetFloat("isoLevel", isoLevel);

            shader.Dispatch(0, numThreadsPerAxis, numThreadsPerAxis, numThreadsPerAxis);
        }

        ComputeBuffer.CopyCount(triangleBuffer, triCountBuffer, 0);

        void HandleReadBack()
        {
            int[] triCountArray = { 0 };
            triCountBuffer.GetData(triCountArray);

            int numTris = triCountArray[0];

            if (numTris > maxTris || tris == null || vertices == null || meshTriangles == null)
            {
                maxTris       = numTris;
                tris          = new Triangle[numTris];
                vertices      = new Vector3[numTris * 3];
                meshTriangles = new int[numTris * 3];
            }

            // Get triangle data from shader
            triangleBuffer.GetData(tris, 0, 0, numTris);

            Mesh mesh = chunk.mesh;

            mesh.Clear();

            for (int i = 0; i < numTris; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    meshTriangles[i * 3 + j] = i * 3 + j;
                    vertices[i * 3 + j]      = tris[i][j];
                }
            }
            mesh.vertices  = vertices;
            mesh.triangles = meshTriangles;
            var scale = chunk.GetComponent <Transform>().localScale;

            mesh.SetUVs(0, UvCalculator.CalculateUVs(vertices, scale.magnitude));
            NormalSolver.RecalculateNormals(mesh, normalDegrees);

            chunk.UpdateColliders();
        }

        if (!blockGpu)
        {
            chunk.asyncOp0 = null;
            chunk.asyncOp1 = null;
            chunk.asyncOp2 = null;
            var async0 = AsyncGPUReadback.Request(pointsBuffer, delegate(AsyncGPUReadbackRequest a0)
            {
                SetupShader();
                var async1 = AsyncGPUReadback.Request(triangleBuffer, delegate(AsyncGPUReadbackRequest a1)
                {
                    // Get number of triangles in the triangle buffer
                    ComputeBuffer.CopyCount(triangleBuffer, triCountBuffer, 0);
                    var async2 = AsyncGPUReadback.Request(triCountBuffer, delegate(AsyncGPUReadbackRequest a2)
                    {
                        HandleReadBack();
                    });
                    chunk.asyncOp2 = async2;
                });
                chunk.asyncOp1 = async1;
            });
            chunk.asyncOp0 = async0;
        }
        else
        {
            SetupShader();
            ComputeBuffer.CopyCount(triangleBuffer, triCountBuffer, 0);
            HandleReadBack();
        }
    }
示例#27
0
        public void BigUploads()
        {
            if (!SystemInfo.supportsComputeShaders)
            {
                Assert.Ignore("Skipped due to platform/computer not supporting compute shaders");
                return;
            }

            var initialData = new ExampleStruct[4 * 1024];

            for (int i = 0; i < initialData.Length; ++i)
            {
                initialData[i] = new ExampleStruct {
                    someData = i
                };
            }

            var buffer = new ComputeBuffer(initialData.Length, UnsafeUtility.SizeOf <ExampleStruct>());

            buffer.SetData(initialData);

            var uploader = new SparseUploader(buffer);


            var newData = new ExampleStruct[312];

            for (int i = 0; i < newData.Length; ++i)
            {
                newData[i] = new ExampleStruct {
                    someData = i + 3000
                };
            }

            var newData2 = new ExampleStruct[316];

            for (int i = 0; i < newData2.Length; ++i)
            {
                newData2[i] = new ExampleStruct {
                    someData = i + 4000
                };
            }

            var tsu = uploader.Begin(UnsafeUtility.SizeOf <ExampleStruct>() * (newData.Length + newData2.Length), 2);

            unsafe
            {
                fixed(void *ptr = newData)
                {
                    tsu.AddUpload(ptr, newData.Length * 4, 512 * 4);
                }

                fixed(void *ptr2 = newData2)
                {
                    tsu.AddUpload(ptr2, newData2.Length * 4, 1136 * 4);
                }
            }

            uploader.EndAndCommit(tsu);

            var resultingData = new ExampleStruct[initialData.Length];

            buffer.GetData(resultingData);

            for (int i = 0; i < resultingData.Length; ++i)
            {
                if (i < 512)
                {
                    Assert.AreEqual(i, resultingData[i].someData);
                }
                else if (i < 824)
                {
                    Assert.AreEqual(i - 512 + 3000, resultingData[i].someData);
                }
                else if (i < 1136)
                {
                    Assert.AreEqual(i, resultingData[i].someData);
                }
                else if (i < 1452)
                {
                    Assert.AreEqual(i - 1136 + 4000, resultingData[i].someData);
                }
                else
                {
                    Assert.AreEqual(i, resultingData[i].someData);
                }
            }

            uploader.Dispose();
            buffer.Dispose();
        }
示例#28
0
        protected override void Compute()
        {
            const string method = nameof(Compute);

            logger.Log(Logger.EventType.Method, $"{Context(method)}: started.");

            stopwatch.Record(Category.Buffer, SetShaderConstants);

            // get kernel handles.
            stopwatch.Start(Category.Shader);
            var handlePart1       = shader.FindKernel("get_dists_part1");
            var handleAbsorptions = shader.FindKernel("get_absorptions");

            stopwatch.Stop(Category.Shader);
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Retrieved kernel handles.");


            // make buffers.
            var outputBufferCell   = new ComputeBuffer(coordinates.Length, sizeof(float) * 2);
            var outputBufferSample = new ComputeBuffer(coordinates.Length, sizeof(float) * 2);
            var absorptionsBuffer  = new ComputeBuffer(coordinates.Length, sizeof(float) * 3);

            logger.Log(Logger.EventType.Data, $"{Context(method)}: Created buffers.");

            stopwatch.Record(Category.Buffer, () =>
            {
                _inputBuffer.SetData(coordinates);

                // set buffers for part1 kernel.
                shader.SetBuffer(handlePart1, "coordinates", _inputBuffer);
                shader.SetBuffer(handlePart1, "distances_sample", outputBufferSample);
                shader.SetBuffer(handlePart1, "distances_cell", outputBufferCell);
            });
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Wrote data to buffers.");


            // compute part1 distances.
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: part1 distances kernel dispatch.");
            stopwatch.Record(Category.Shader, () => shader.Dispatch(handlePart1, threadGroupsX, 1, 1));
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: part1 distances kernel return.");


            var absorptions = new Vector3[_nrCoordinates];

            Array.Clear(absorptions, 0, absorptions.Length);

            stopwatch.Record(Category.Buffer, () => shader.SetBuffer(handleAbsorptions, "coordinates", _inputBuffer));

            // for each angle:
            for (int j = 0; j < _nrAnglesTheta; j++)
            {
                var j1 = j;
                stopwatch.Record(Category.Buffer, () =>
                {
                    shader.SetFloats("rot", (float)Math.Cos(Math.PI - GetThetaAt(j1)),
                                     (float)Math.Sin(Math.PI - GetThetaAt(j1)));
                    shader.SetBuffer(handleAbsorptions, "distances_sample", outputBufferSample);
                    shader.SetBuffer(handleAbsorptions, "distances_cell", outputBufferCell);
                    shader.SetBuffer(handleAbsorptions, "absorptions", absorptionsBuffer);
                });
                stopwatch.Record(Category.Shader, () => shader.Dispatch(handleAbsorptions, threadGroupsX, 1, 1));
                stopwatch.Record(Category.Buffer, () => absorptionsBuffer.GetData(absorptions));

                _absorptionFactors[j] = GetAbsorptionFactor(absorptions);
            }

            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Calculated all absorptions.");

            // release buffers.
            stopwatch.Record(Category.Buffer, () =>
            {
                _inputBuffer.Release();
                outputBufferCell.Release();
                outputBufferSample.Release();
                absorptionsBuffer.Release();
            });
            logger.Log(Logger.EventType.ShaderInteraction, $"{Context(method)}: Shader buffers released.");

            logger.Log(Logger.EventType.Method, $"{Context(method)}: done.");
        }
示例#29
0
    public void TestComputeShader(Vector3 postion, float[] heightmap)
    {
        Init_perm(0);

        int f_sizeX   = 10;
        int f_sizeZ   = 10;
        int perMeterX = 4;
        int perMeterZ = 4;

        int voxelOffset_x = 10;
        int voxelOffset_y = 10;

        Heightmap = heightmap;

        intermediate = new Plant[f_sizeX * perMeterX * f_sizeZ * perMeterZ];
        int indexBuff_size = f_sizeX * perMeterX * f_sizeZ * perMeterZ * 8 * 3;

        Debug.Log("indexBuff_size: " + indexBuff_size);
        vertexData = new VertexData[indexBuff_size];
        indices    = GenIndices(f_sizeX * perMeterX, f_sizeZ * perMeterZ);


        ComputeBuffer buffer = new ComputeBuffer(heightmap.Length, sizeof(float));

        buffer.SetData(heightmap);

        ComputeBuffer output_buff = new ComputeBuffer(intermediate.Length, Plant.GetSize());

        output_buff.SetData(intermediate);

        //ComputeBuffer g_buff = new ComputeBuffer(indexBuff_size, sizeof(int));
        GraphicsBuffer g_buff = new GraphicsBuffer(GraphicsBuffer.Target.Index, indices.Length, sizeof(int));

        g_buff.SetData(indices);

        ComputeBuffer v_buff = new ComputeBuffer(indexBuff_size, VertexData.GetSize());

        v_buff.SetData(vertexData);


        int k   = shader.FindKernel("CSMain");
        int c_k = shader.FindKernel("CompileMesh");

        shader.SetInt("sizeX", SmoothVoxelSettings.ChunkSizeX);
        shader.SetInt("sizeZ", SmoothVoxelSettings.ChunkSizeZ);
        shader.SetInt("f_sizeX", f_sizeX);
        shader.SetInt("f_sizeZ", f_sizeZ);
        shader.SetInt("perMeterX", perMeterX);
        shader.SetInt("perMeterZ", perMeterZ);
        shader.SetInt("voxel_offset_x", voxelOffset_x);
        shader.SetInt("voxel_offset_z", voxelOffset_y);
        shader.SetBuffer(k, "heightmap", buffer);
        shader.SetBuffer(k, "intermediate", output_buff);

        shader.SetBuffer(c_k, "intermediate", output_buff);
        //shader.SetBuffer(c_k, "indices", g_buff);
        shader.SetBuffer(c_k, "vertex", v_buff);

        shader.Dispatch(k, f_sizeX * 4, 1, f_sizeZ * 4);
        shader.Dispatch(c_k, 1, 1, 1);


        v_buff.GetData(vertexData);
        g_buff.GetData(indices);

        verts   = new List <Vector3>();
        uv      = new List <Vector2>();
        normals = new List <Vector3>();

        for (int i = 0; i < indexBuff_size; i++)
        {
            verts.Add(vertexData[i].Vertex);
            uv.Add(vertexData[i].UV);
            normals.Add(vertexData[i].Normal);
        }

        rend = GetComponent <MeshRenderer>();

        rend.material.SetPass(0);
        rend.material.SetBuffer("_Vertex", v_buff);
        rend.material.SetTexture("_permutation", perm_tex);

        MeshFilter filter = gameObject.GetComponent <MeshFilter>();
        Mesh       mesh   = new Mesh();

        mesh.vertices  = new Vector3[indexBuff_size];//verts.ToArray();
        mesh.triangles = indices;
        //mesh.uv = uv.ToArray();

        Vector3 corner = postion;
        //new Bounds()
        Bounds b = new Bounds(corner + new Vector3(SmoothVoxelSettings.MeterSizeX / 2 - 0.5f, SmoothVoxelSettings.MeterSizeY / 2 - 0.5f, SmoothVoxelSettings.MeterSizeZ / 2 - 0.5f),
                              new Vector3(SmoothVoxelSettings.MeterSizeX + 1, SmoothVoxelSettings.MeterSizeY + 1, SmoothVoxelSettings.MeterSizeZ + 1));

        mesh.bounds = b;

        filter.sharedMesh = mesh;

        inited = true;

        //Vector3 corner = postion + new Vector3(voxelOffset_x, 0, voxelOffset_y);
        //Bounds b = new Bounds(corner + new Vector3(f_sizeX / 2, SmoothVoxelSettings.ChunkSizeY / 2, f_sizeZ / 2), new Vector3(f_sizeX / 2, SmoothVoxelSettings.ChunkSizeY / 2, f_sizeZ / 2));



        //Graphics.DrawProcedural(rend.material, b, MeshTopology.Triangles, indexBuff_size);
        // Graphics.DrawProceduralIndirect(rend.material, b, MeshTopology.Triangles, g_buff);
        //Graphics.DrawProcedural(rend.material, b, MeshTopology.Triangles, g_buff, indices.Length);

        return;

        output_buff.GetData(intermediate);


        List <int> tris = new List <int>();

        for (int x = 0; x < f_sizeX * 4; x++)
        {
            for (int z = 0; z < f_sizeZ * 4; z++)
            {
                Plant res = intermediate[x * (f_sizeZ * 4) + z];

                int offset = verts.Count;

                verts.AddRange(res.q1.GetVerts());
                tris.AddRange(res.q1.GetTris(offset));
                uv.AddRange(res.q1.GetUVs());

                verts.AddRange(res.q2.GetVerts());
                tris.AddRange(res.q2.GetTris(offset));
                uv.AddRange(res.q2.GetUVs());

                verts.AddRange(res.q3.GetVerts());
                tris.AddRange(res.q3.GetTris(offset));
                uv.AddRange(res.q3.GetUVs());

                //Debug.DrawRay(verts[0], res.normal, Color.green, 1000000);

                //Debug.Log("|" + res.q1.ToString() + " " + res.q2.ToString() + " " + res.q3.ToString() + " | ");

                //Vector4 res = output[x * (20 * 4) + z];

                //Vector3 normal = res;
                //float height = res.w;

                //Vector3 point = new Vector3(x / 4f, height, z / 4f);
                //Debug.DrawRay(point, normal, Color.green, 1000000);

                /*if (x % 8 == 0 &&
                 *  z % 8 == 0)
                 * {
                 *  Vector3 t1 = GetTangent(normal, Vector3.forward);
                 *  Vector3 t2 = GetTangent(normal, Vector3.right);
                 *
                 *  Quaternion q1 = Quaternion.LookRotation(normal, Vector3.up);
                 *  //Quaternion q2 = Quaternion.LookRotation(t2, Vector3.up);
                 *
                 *
                 *
                 *  Debug.DrawRay(point, normal, Color.green, 1000000);
                 *  //Debug.DrawRay(point, t1, Color.blue, 1000000);
                 *  //Debug.DrawRay(point, t2, Color.red, 1000000);
                 *  //Quaternion quat = q1 * q2;
                 *  //Instantiate(obj, point, q1);
                 * }*/
            }
        }

        Debug.Log("Num tris: " + tris.Count);

        mesh.vertices  = verts.ToArray();
        mesh.triangles = tris.ToArray();
        mesh.uv        = uv.ToArray();

        mesh.RecalculateNormals();

        filter.sharedMesh = mesh;
    }
    public void BuildMesh()
    {
        float startTime = Time.realtimeSinceStartup;

        // NOISE VOLUME!
        RenderTexture DensityVolume = new RenderTexture(16, 16, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.sRGB);

        DensityVolume.volumeDepth       = 16;
        DensityVolume.isVolume          = true;
        DensityVolume.enableRandomWrite = true;
        DensityVolume.filterMode        = FilterMode.Bilinear;
        DensityVolume.wrapMode          = TextureWrapMode.Repeat;
        DensityVolume.Create();
        int mgen_id = CShaderSimplex.FindKernel("FillEmpty");

        // uses renderTexture rather than StructuredBuffer?
        CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume); // Links RenderTexture to the "Result" RWTexture in the compute shader?
        CShaderSimplex.Dispatch(mgen_id, 1, 1, 16);                  // run computeShader "FillEmpty" with 1 x 1 x 31 threadGroups?
        mgen_id = CShaderSimplex.FindKernel("Simplex3d");
        CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume);
        CShaderSimplex.Dispatch(mgen_id, 1, 1, 16);  // Fill shared RenderTexture with GPU simplex Noise


        ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4));

        cBufferSegmentTransform.SetData(critterSegmentTransforms);
        int kernelID = CShaderBuildMC.FindKernel("CSMain");

        CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform);
        CShaderBuildMC.SetTexture(kernelID, "noise_volume", DensityVolume);  // Noise 3D texture
        //Debug.Log(DensityVolume.colorBuffer.ToString());

        // Figure out how many chunks are needed:
        int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x / (cellResolution * 8f));
        int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y / (cellResolution * 8f));
        int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z / (cellResolution * 8f));
        //Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")");

        int totalNumChunks = numChunksX * numChunksY * numChunksZ;

        Poly[][] PolyArrayArray = new Poly[totalNumChunks][];  // This will hold the mesh data from the chunks calculated on the GPU
        int[]    numPolysArray  = new int[totalNumChunks];
        int      totalNumPolys  = 0;

        // Get each chunk!
        int chunkIndex = 0;

        for (int x = 0; x < numChunksX; x++)
        {
            for (int y = 0; y < numChunksY; y++)
            {
                for (int z = 0; z < numChunksZ; z++)
                {
                    // Figure out chunk offset amount:
                    Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z) + GlobalBoundingBoxOffset - (GlobalBoundingBoxDimensions / 2f);

                    int[]         numPolys       = new int[1];
                    ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int));
                    cBufferNumPoly.SetData(numPolys);

                    int id = CShaderBuildMC.FindKernel("CSMain");
                    CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer
                    CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x);
                    CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y);
                    CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z);
                    CShaderBuildMC.SetFloat("_CellSize", cellResolution);
                    CShaderBuildMC.SetVector("_ColorPrimary", colorPrimary);
                    CShaderBuildMC.SetVector("_ColorSecondary", colorSecondary);
                    CShaderBuildMC.SetFloat("_ColorNoiseScale", colorNoiseScale);
                    CShaderBuildMC.SetFloat("_ColorSmlAmplitude", colorSmlAmplitude);
                    CShaderBuildMC.SetFloat("_ColorMedAmplitude", colorMedAmplitude);
                    CShaderBuildMC.SetFloat("_ColorLrgAmplitude", colorLrgAmplitude);
                    CShaderBuildMC.SetFloat("_ColorContrast", colorContrast);
                    CShaderBuildMC.SetFloat("_ColorThreshold", colorThreshold);
                    CShaderBuildMC.SetVector("_SkinNoiseScale", skinNoiseScale);
                    CShaderBuildMC.SetFloat("_SkinNoiseAmplitude", skinNoiseAmplitude);
                    CShaderBuildMC.SetVector("_SkinLocalTaper", skinLocalTaper);
                    CShaderBuildMC.SetVector("_SkinLocalSinFreq", skinLocalSinFreq);
                    CShaderBuildMC.SetVector("_SkinLocalSinAmp", skinLocalSinAmp);
                    // Local Segment-space modifications, sin, taper, etc.

                    CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly);
                    CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys
                    cBufferNumPoly.GetData(numPolys);     // get numPolys
                    //Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkOffset: " + chunkOffset.ToString());
                    totalNumPolys            += numPolys[0];
                    numPolysArray[chunkIndex] = numPolys[0];

                    if (numPolys[0] > 0)     // only do this if there was at least 1 triangle in the test pass
                    {
                        Poly[]        polyArray     = new Poly[numPolys[0]];
                        int           cBufferStride = sizeof(float) * (18 + 9 + 6) + sizeof(int) * (6);
                        ComputeBuffer cBuffer       = new ComputeBuffer(numPolys[0], cBufferStride); // 18 floats x 4 bytes/float = 72   + COLORS! 9 x 4 = 36  = 108   + BONES! 6x4 = 24 + 6 xint...
                        cBuffer.SetData(polyArray);

                        CShaderBuildMC.SetBuffer(id, "buffer", cBuffer);
                        CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris
                        CShaderBuildMC.Dispatch(id, 1, 1, 1);
                        cBuffer.GetData(polyArray);                // return data from GPU

                        PolyArrayArray[chunkIndex] = polyArray;
                        cBuffer.Dispose();
                    }

                    cBufferNumPoly.Dispose();

                    chunkIndex++;
                }
            }
        }


        CritterDecorationsTest.decorationStruct[] points = new CritterDecorationsTest.decorationStruct[totalNumPolys];

        //Construct mesh using received data
        int vindex   = 0;
        int decindex = 0;

        // Why same number of tris as vertices?  == // because all triangles have duplicate verts - no shared vertices?
        Vector3[]    vertices = new Vector3[totalNumPolys * 3];
        Color[]      colors   = new Color[totalNumPolys * 3];
        int[]        tris     = new int[totalNumPolys * 3];
        Vector2[]    uvs      = new Vector2[totalNumPolys * 3];
        Vector3[]    normals  = new Vector3[totalNumPolys * 3];
        BoneWeight[] weights  = new BoneWeight[totalNumPolys * 3];

        //Parse triangles
        for (int i = 0; i < PolyArrayArray.Length; i++)
        {
            if (numPolysArray[i] > 0)    // only do this if there was at least 1 triangle in the test pass
            {
                for (int ix = 0; ix < numPolysArray[i]; ix++)
                {
                    Vector3 vPos;
                    Vector3 vOffset = new Vector3(0, 0, 0);   //???  offsets all vertices by this amount, but why 30??
                                                              //A1,A2,A3
                    vPos                       = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset;
                    vertices[vindex]           = vPos * _Scale;
                    normals[vindex]            = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3);
                    tris[vindex]               = vindex;
                    uvs[vindex]                = new Vector2(vertices[vindex].z, vertices[vindex].x);
                    colors[vindex]             = new Color(PolyArrayArray[i][ix].CAR, PolyArrayArray[i][ix].CAG, PolyArrayArray[i][ix].CAB, 1.0f);
                    weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexA0;
                    weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexA1;
                    weights[vindex].weight0    = PolyArrayArray[i][ix].BoneWeightA0;
                    weights[vindex].weight1    = PolyArrayArray[i][ix].BoneWeightA1;

                    points[decindex].pos    = vPos;
                    points[decindex].normal = normals[vindex];
                    points[decindex].color  = new Vector3(colors[vindex].r, colors[vindex].g, colors[vindex].b);

                    decindex++;
                    vindex++;

                    //B1,B2,B3
                    vPos                       = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset;
                    vertices[vindex]           = vPos * _Scale;
                    normals[vindex]            = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3);
                    tris[vindex]               = vindex;
                    uvs[vindex]                = new Vector2(vertices[vindex].z, vertices[vindex].x);
                    colors[vindex]             = new Color(PolyArrayArray[i][ix].CBR, PolyArrayArray[i][ix].CBG, PolyArrayArray[i][ix].CBB, 1.0f);
                    weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexB0;
                    weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexB1;
                    weights[vindex].weight0    = PolyArrayArray[i][ix].BoneWeightB0;
                    weights[vindex].weight1    = PolyArrayArray[i][ix].BoneWeightB1;

                    vindex++;

                    //C1,C2,C3
                    vPos                       = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset;
                    vertices[vindex]           = vPos * _Scale;
                    normals[vindex]            = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3);
                    tris[vindex]               = vindex;
                    uvs[vindex]                = new Vector2(vertices[vindex].z, vertices[vindex].x);
                    colors[vindex]             = new Color(PolyArrayArray[i][ix].CCR, PolyArrayArray[i][ix].CCG, PolyArrayArray[i][ix].CCB, 1.0f);
                    weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexC0;
                    weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexC1;
                    weights[vindex].weight0    = PolyArrayArray[i][ix].BoneWeightC0;
                    weights[vindex].weight1    = PolyArrayArray[i][ix].BoneWeightC1;

                    vindex++;
                }
            }
        }

        //We have got all data and are ready to setup a new mesh!
        Mesh newMesh = new Mesh();

        newMesh.vertices  = vertices;
        newMesh.uv        = uvs;     //Unwrapping.GeneratePerTriangleUV(NewMesh);
        newMesh.triangles = tris;
        newMesh.normals   = normals; //NewMesh.RecalculateNormals();
        newMesh.colors    = colors;
        newMesh.Optimize();

        // Set up SKINNING!!!:
        Transform[] bones     = new Transform[critter.critterSegmentList.Count];
        Matrix4x4[] bindPoses = new Matrix4x4[critter.critterSegmentList.Count];
        // Try just using existing critter's GameObjects/Transforms:
        for (int seg = 0; seg < critter.critterSegmentList.Count; seg++)
        {
            bones[seg]     = critter.critterSegmentList[seg].transform;
            bindPoses[seg] = bones[seg].worldToLocalMatrix * transform.localToWorldMatrix;  // ?????????????????
            // the bind pose is the inverse of inverse transformation matrix of the bone, when the bone is in the bind pose .... unhelpful ....
        }
        newMesh.boneWeights = weights;
        newMesh.bindposes   = bindPoses;
        SkinnedMeshRenderer skinnedMeshRenderer = this.GetComponent <SkinnedMeshRenderer>();

        skinnedMeshRenderer.bones      = bones;
        skinnedMeshRenderer.sharedMesh = newMesh;
        skinnedMeshRenderer.enabled    = true;

        cBufferSegmentTransform.Release();

        critterDecorationsTest.TurnOn(points);

        float calcTime = Time.realtimeSinceStartup - startTime;

        Debug.Log("MeshCreated! " + calcTime.ToString());
    }