public void UpdateChunkMesh(Chunk chunk)
    {
        int   numVoxelsPerAxis  = numPointsPerAxis - 1;
        int   numThreadsPerAxis = Mathf.CeilToInt(numVoxelsPerAxis / (float)threadGroupSize);
        float pointSpacing      = boundsSize / (numPointsPerAxis - 1);

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

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

        if (chunk.Saved)
        {
            pointsBuffer.SetData(chunk.Points);
        }
        else
        {
            densityGenerator.Generate(pointsBuffer, numPointsPerAxis, boundsSize, worldBounds, centre, offset, pointSpacing);
            pointsBuffer.GetData(chunk.Points);
            chunk.Saved = true;
        }
        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);

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

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

        Mesh mesh = chunk.mesh;

        mesh.Clear();

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

        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;

        mesh.RecalculateNormals();
        chunk.SetUp(mat, generateColliders);
    }
    public void UpdateChunk(Chunk chunk)
    {
        int        numVertsPerAxis = resolution + 1;
        Vector3    mapSize         = (Vector3)numberOfChunks * chunkSize;
        float      vertSpacing     = chunkSize / resolution;
        Vector3Int position        = chunk.position;
        Vector3    center          = GetChunkCenterFromPosition(position);

        // Obtain density of each vertex
        densityGenerator.Generate(vertexBuffer, numVertsPerAxis, chunkSize, vertSpacing, mapSize, center, densityOffset);

        // Set up compute shader
        int kernelIndex = chunkShader.FindKernel("CubeMarch");

        triangleBuffer.SetCounterValue(0);
        chunkShader.SetBuffer(kernelIndex, "vertexBuffer", vertexBuffer);
        chunkShader.SetBuffer(kernelIndex, "triangleBuffer", triangleBuffer);
        chunkShader.SetInt("resolution", resolution);
        chunkShader.SetFloat("surfaceLevel", surfaceLevel);
        chunkShader.Dispatch(kernelIndex, 8, 8, 8);

        // Obtain compute shader result
        int[] numTriangleOut = { 0 };
        ComputeBuffer.CopyCount(triangleBuffer, numTriangleBuffer, 0);
        numTriangleBuffer.GetData(numTriangleOut);
        int numTriangles = numTriangleOut[0];

        Triangle[] triangleList = new Triangle[numTriangles];
        triangleBuffer.GetData(triangleList, 0, 0, numTriangles);

        // Generate mesh
        Mesh mesh = chunk.mesh;

        Vector3[] vertices  = new Vector3[numTriangles * 3];
        int[]     triangles = new int[numTriangles * 3];

        for (int triIndex = 0; triIndex < numTriangles; triIndex++)
        {
            for (int vertIndex = 0; vertIndex < 3; vertIndex++)
            {
                vertices[triIndex * 3 + vertIndex]  = triangleList[triIndex][vertIndex];
                triangles[triIndex * 3 + vertIndex] = triIndex * 3 + vertIndex;
            }
        }

        mesh.Clear();
        mesh.vertices  = vertices;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();
    }
Beispiel #3
0
    public void UpdateChunkMesh(Chunk chunk)
    {
        int   voxelsPerAxis    = pointsPerAxis - 1;
        int   voxels           = voxelsPerAxis * voxelsPerAxis * voxelsPerAxis;
        int   maxTriangleCount = voxels * 5;
        float pointSpacing     = boundsSize / (pointsPerAxis - 1);

        Vector3Int coord  = chunk.coord;
        Vector3    center = CenterFromCoord(coord);

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

        Vector4[]       points    = densityGenerator.Generate(pointsPerAxis, boundsSize, worldBounds, center, offset, pointSpacing);
        List <Triangle> triangles = new List <Triangle>();


        for (int z = 0; z < pointsPerAxis - 1; z++)
        {
            for (int y = 0; y < pointsPerAxis - 1; y++)
            {
                for (int x = 0; x < pointsPerAxis - 1; x++)
                {
                    March(points, new Vector3Int(x, y, z), triangles);
                }
            }
        }

        int numTris = triangles.Count;

        Mesh mesh = chunk.mesh;

        mesh.Clear();

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

        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]      = triangles[i][2 - j];
            }
        }
        mesh.vertices  = vertices;
        mesh.triangles = meshTriangles;

        mesh.RecalculateNormals();
    }
    public void UpdateChunkMesh(Chunk chunk)
    {
        int   numVoxelsPerAxis  = numPointsPerAxis - 1;
        int   numThreadsPerAxis = Mathf.CeilToInt(numVoxelsPerAxis / (float)threadGroupSize);
        float pointSpacing      = _pointSpacing; // boundsSize / (numPointsPerAxis - 1);

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

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

        /*
         * if (storeData && storedData.Count == Mathf.Pow(numPointsPerAxis, 3)) {
         *  pointsBuffer.SetData(storedData);
         * }
         * else {
         *  densityGenerator.Generate(pointsBuffer, numPointsPerAxis, boundsSize, worldBounds, centre, offset, pointSpacing);
         *  Vector4[] data = new Vector4[numPointsPerAxis * numPointsPerAxis * numPointsPerAxis];
         *  pointsBuffer.GetData(data);
         *  storedData.RemoveRange(0, storedData.Count);
         *  storedData.AddRange(data);
         * }*/
        if (storeData)
        {
            pointsBuffer.SetData(storedData);
        }
        else
        {
            densityGenerator.Generate(pointsBuffer, numPointsPerAxis, boundsSize, worldBounds, centre, offset, pointSpacing);
        }

        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);

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

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

        Mesh mesh = chunk.mesh;

        mesh.Clear();

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

        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];

                /*
                 * vertices[i * 3 + j].y -= Mathf.RoundToInt((vertices[i * 3 + j].y + 1) / 3);
                 * vertices[i * 3 + j].y -= Mathf.RoundToInt((vertices[i * 3 + j].y - 0.5f) / 2);
                 * vertices[i * 3 + j].x -= Mathf.RoundToInt((vertices[i * 3 + j].x + 1) / 3);
                 * vertices[i * 3 + j].x -= Mathf.RoundToInt((vertices[i * 3 + j].x - 0.5f) / 2);
                 * vertices[i * 3 + j].z -= Mathf.RoundToInt((vertices[i * 3 + j].z + 1) / 3);
                 * vertices[i * 3 + j].z -= Mathf.RoundToInt((vertices[i * 3 + j].z - 0.5f) / 2);
                 */
            }
        }

        mesh.vertices  = vertices;
        mesh.triangles = meshTriangles;

        mesh.RecalculateNormals();
        //mesh.Optimize();
    }
Beispiel #5
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();
        }
    }
Beispiel #6
0
    public void UpdateChunkMesh(Chunk chunk)
    {
        Vector3Int coord        = chunk.coord;
        Vector3    centre       = CentreFromCoord(coord);
        float      pointSpacing = boundsSize / (numPointsPerAxis - 1);

        if (chunk.pointsBuffer == null)
        {
            int numPoints = numPointsPerAxis * numPointsPerAxis * numPointsPerAxis;

            ComputeBuffer pointsBuffer = new ComputeBuffer(numPoints, sizeof(float));

            densityGenerator.Generate(pointsBuffer, numPointsPerAxis, boundsSize, centre, offset, pointSpacing);
            chunk.pointsBuffer = pointsBuffer;
            chunk.numPoints    = numPoints;
        }

        int numVoxelsPerAxis  = numPointsPerAxis - 1;
        int numThreadsPerAxis = Mathf.CeilToInt(numVoxelsPerAxis / (float)threadGroupSize);

        triangleBuffer.SetCounterValue(0);
        shader.SetBuffer(0, "points", chunk.pointsBuffer);
        shader.SetBuffer(0, "triangles", triangleBuffer);
        shader.SetInt("numPointsPerAxis", numPointsPerAxis);
        shader.SetFloat("isoLevel", isoLevel);
        shader.SetFloat("boundsSize", boundsSize);
        shader.SetVector("centre", new Vector4(centre.x, centre.y, centre.z));
        shader.SetVector("offset", new Vector4(offset.x, offset.y, offset.z));
        shader.SetFloat("spacing", pointSpacing);

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

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

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

        Mesh mesh = chunk.mesh;

        mesh.Clear();

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

        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;

        mesh.RecalculateNormals();
        mesh.Optimize();

        MeshFilter meshFilter = chunk.GetComponent <MeshFilter>();

        meshFilter.sharedMesh = mesh;

        MeshCollider meshCollider = chunk.GetComponent <MeshCollider>();

        meshCollider.sharedMesh = mesh;
    }