Esempio n. 1
0
    private bool ComputeNewVoxels(ComputeShader shader, ThreadedChunkLoader thread, Chunk chunk, Vector3 min, int octreeSize)
    {
        float gpuStart = Time.realtimeSinceStartup;


        float[] chunkPos = new float[3] {
            min.x, min.y, min.z
        };
        shader.SetFloats("chunkPosition", chunkPos);

        shader.SetInt("resolution", octreeSize);
        shader.SetInt("octreeSize", octreeSize);

        int[] zero = new int[1] {
            0
        };

        float sqRTRC  = Mathf.Sqrt(octreeSize * octreeSize * octreeSize);
        int   sqRTRes = (int)sqRTRC;

        if (sqRTRC > sqRTRes)
        {
            sqRTRes++;
        }

        int[] zeroSq = new int[sqRTRes];
        for (int i = 0; i < sqRTRes; i++)
        {
            zeroSq[i] = 0;
        }

        ComputeBuffer Perm = new ComputeBuffer(512, sizeof(int));

        Perm.SetData(permutations);

        ComputeBuffer cornCount       = new ComputeBuffer(sqRTRes, sizeof(int));
        ComputeBuffer finalCount      = new ComputeBuffer(1, sizeof(int));
        ComputeBuffer voxMatBuffer    = new ComputeBuffer(octreeSize * octreeSize * octreeSize, sizeof(uint));
        ComputeBuffer cornerMaterials = new ComputeBuffer((octreeSize + 1) * (octreeSize + 1) * (octreeSize + 1), sizeof(uint));

        shader.SetInt("primitiveModCount", chunk.modCount);
        ComputeBuffer PrimMods = null;

        if (chunk.modCount > 0)
        {
            PrimMods = new ComputeBuffer(chunk.modCount, (sizeof(int) * 2) + (sizeof(float) * 6));
            PrimMods.SetData(chunk.primitiveMods);
        }


        int kernel = shader.FindKernel("ComputeMaterials");

        if (chunk.modCount > 0)
        {
            shader.SetBuffer(kernel, "primitiveMods", PrimMods);
        }
        shader.SetBuffer(kernel, "Perm", Perm);
        shader.SetBuffer(kernel, "cornerMaterials", cornerMaterials);
        shader.Dispatch(kernel, 1, 1, 1);

        kernel = shader.FindKernel("ComputeCorners");
        shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer);
        shader.SetBuffer(kernel, "cornerCount", cornCount);
        shader.SetBuffer(kernel, "cornerMaterials", cornerMaterials);
        cornCount.SetData(zeroSq);
        shader.Dispatch(kernel, 1, 1, 1);

        kernel = shader.FindKernel("AddLength");
        shader.SetBuffer(kernel, "cornerCount", cornCount);
        shader.SetBuffer(kernel, "finalCount", finalCount);
        finalCount.SetData(zero);
        shader.Dispatch(kernel, 1, 1, 1);

        int[] voxelCount = new int[1];
        finalCount.GetData(voxelCount);
        int count = voxelCount[0];

        if (count <= 0)
        {
            voxMatBuffer.Dispose();
            cornerMaterials.Dispose();
            cornCount.Dispose();
            finalCount.Dispose();
            Perm.Dispose();
            if (chunk.modCount > 0)
            {
                PrimMods.Dispose();
                PrimMods = null;
            }
            Perm            = null;
            voxMatBuffer    = null;
            cornerMaterials = null;
            cornCount       = null;
            finalCount      = null;
            return(false);
        }

        //Debug.Log (count);

        ComputeBuffer cornerIndexes = new ComputeBuffer(count, sizeof(uint));

        kernel = shader.FindKernel("ComputePositions");
        shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer);
        shader.SetBuffer(kernel, "cornerCount", cornCount);
        shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes);
        shader.Dispatch(kernel, 1, 1, 1);

        ComputeBuffer voxBuffer      = new ComputeBuffer(count, (sizeof(float) * 6) + sizeof(int));
        ComputeBuffer positionBuffer = new ComputeBuffer(count, sizeof(float) * 3);

        kernel = shader.FindKernel("ComputeVoxels");
        if (chunk.modCount > 0)
        {
            shader.SetBuffer(kernel, "primitiveMods", PrimMods);
        }
        shader.SetBuffer(kernel, "Perm", Perm);
        shader.SetBuffer(kernel, "voxMins", positionBuffer);
        shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer);
        shader.SetBuffer(kernel, "finalCount", finalCount);
        shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes);
        shader.SetBuffer(kernel, "voxels", voxBuffer);
        shader.Dispatch(kernel, (count / 128) + 1, 1, 1);

        Vector3[] voxelMins = new Vector3[count];
        positionBuffer.GetData(voxelMins);
        positionBuffer.Dispose();
        positionBuffer = null;

        uint[] voxelMaterials = new uint[count];
        cornerIndexes.GetData(voxelMaterials);
        cornerIndexes.Dispose();
        cornerIndexes = null;

        GPUVOX[] voxs = new GPUVOX[count];
        voxBuffer.GetData(voxs);
        voxBuffer.Dispose();
        voxBuffer = null;

        voxMatBuffer.Dispose();
        cornerMaterials.Dispose();
        cornCount.Dispose();
        finalCount.Dispose();
        Perm.Dispose();
        if (chunk.modCount > 0)
        {
            PrimMods.Dispose();
            PrimMods = null;
        }
        Perm            = null;
        voxMatBuffer    = null;
        cornerMaterials = null;
        cornCount       = null;
        finalCount      = null;
        float gpuEnd = Time.realtimeSinceStartup;

        //Debug.Log ("GPU time on chunk: " + (gpuEnd - gpuStart));

        thread.setData(this, count, voxelMins, voxelMaterials, voxs, min, octreeSize);
        thread.setChunkForUpdate(chunk);
        thread.Start();

        return(true);
    }
Esempio n. 2
0
    private List <OctreeNode> ComputeVoxels(ComputeShader shader, Vector3 min, int octreeSize)
    {
        float gpuStart = Time.realtimeSinceStartup;

        float[] chunkPos = new float[3] {
            min.x, min.y, min.z
        };
        shader.SetFloats("chunkPosition", chunkPos);

        shader.SetInt("resolution", octreeSize);
        shader.SetInt("octreeSize", octreeSize);

        float sqRTRC  = Mathf.Sqrt(octreeSize * octreeSize * octreeSize);
        int   sqRTRes = (int)sqRTRC;

        if (sqRTRC > sqRTRes)
        {
            sqRTRes++;
        }

        ComputeBuffer Perm = new ComputeBuffer(512, sizeof(int));

        Perm.SetData(permutations);

        ComputeBuffer cornCount    = new ComputeBuffer(sqRTRes, sizeof(int));
        ComputeBuffer finalCount   = new ComputeBuffer(1, sizeof(float));
        ComputeBuffer voxMatBuffer = new ComputeBuffer(octreeSize * octreeSize * octreeSize, sizeof(uint));

        float rD8  = octreeSize / 8.0f;
        int   rD8I = (int)rD8;

        if (rD8 > rD8I)
        {
            rD8I++;
        }

        int kernel = shader.FindKernel("ComputeCorners");

        shader.SetBuffer(kernel, "Perm", Perm);
        shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer);
        shader.Dispatch(kernel, rD8I, rD8I, rD8I);

        /*kernel = shader.FindKernel("ComputeLength");
         * shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer);
         * shader.SetBuffer(kernel, "cornerCount", cornCount);
         * shader.Dispatch(kernel, 1, 1, 1);*/

        kernel = shader.FindKernel("AddLength");
        shader.SetBuffer(kernel, "cornerCount", cornCount);
        shader.SetBuffer(kernel, "finalCount", finalCount);
        shader.Dispatch(kernel, 1, 1, 1);

        float[] voxelCount = new float[1];
        finalCount.GetData(voxelCount);
        finalCount.SetData(voxelCount);
        int count = (int)voxelCount[0];

        //Debug.Log (count);

        if (count <= 0)
        {
            voxMatBuffer.Dispose();
            cornCount.Dispose();
            finalCount.Dispose();
            Perm.Dispose();
            return(null);
        }

        ComputeBuffer cornerIndexes = new ComputeBuffer(count, sizeof(uint));

        kernel = shader.FindKernel("ComputePositions");
        shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer);
        shader.SetBuffer(kernel, "cornerCount", cornCount);
        shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes);
        shader.Dispatch(kernel, 1, 1, 1);

        ComputeBuffer voxBuffer      = new ComputeBuffer(count, (sizeof(float) * 6) + sizeof(int));
        ComputeBuffer positionBuffer = new ComputeBuffer(count, sizeof(float) * 3);

        kernel = shader.FindKernel("ComputeVoxels");
        shader.SetBuffer(kernel, "Perm", Perm);
        shader.SetBuffer(kernel, "voxMins", positionBuffer);
        shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer);
        shader.SetBuffer(kernel, "finalCount", finalCount);
        shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes);
        shader.SetBuffer(kernel, "voxels", voxBuffer);
        //int dispatchCount = count / 10;
        shader.Dispatch(kernel, (count / 128) + 1, 1, 1);

        List <OctreeNode> computedVoxels = new List <OctreeNode>();

        Vector3[] voxelMins = new Vector3[count];
        positionBuffer.GetData(voxelMins);
        positionBuffer.Dispose();

        uint[] voxelMaterials = new uint[count];
        cornerIndexes.GetData(voxelMaterials);
        cornerIndexes.Dispose();

        GPUVOX[] voxs = new GPUVOX[count];
        voxBuffer.GetData(voxs);
        voxBuffer.Dispose();

        voxMatBuffer.Dispose();
        cornCount.Dispose();
        finalCount.Dispose();
        Perm.Dispose();

        float gpuEnd = Time.realtimeSinceStartup;
        //Debug.Log ("GPU time on chunk: " + (gpuEnd - gpuStart));

        int HIGHEST_VOXEL_RES = 64;
        int voxelSize         = HIGHEST_VOXEL_RES / octreeSize;


        for (int i = 0; i < count; i++)
        {
            if (voxs[i].numPoints != 0)
            {
                OctreeNode leaf = new OctreeNode();
                leaf.type = OctreeNodeType.Node_Leaf;
                leaf.size = voxelSize;
                OctreeDrawInfo drawInfo = new OctreeDrawInfo();
                drawInfo.position      = voxs[i].vertPoint;
                drawInfo.averageNormal = voxs[i].avgNormal;
                drawInfo.corners       = (int)voxelMaterials[i];
                leaf.drawInfo          = drawInfo;
                leaf.min = voxelMins[i];
                computedVoxels.Add(leaf);
            }
        }

        //Debug.Log ("CPU Leaf generation time on chunk: " + (Time.realtimeSinceStartup - gpuEnd));
        //Debug.Log (computedVoxels.Count);

        return(computedVoxels);
    }