Пример #1
0
        // Flood the voxel data with the given voxel and update chunk fill type accordingly
        private void FloodVoxelData(Voxel floodVoxel)
        {
            fillType = FillType.Null;
            TerrainGeneratorBase.ChunkFillUpdate(this, floodVoxel);

            int index = 0;

            for (int i = 0; i < SIZE * SIZE * SIZE; i++)
            {
                voxelData[index++] = floodVoxel;
            }
        }
        // Draw debug info and terrain generator buttons
        void OnGUI()
        {
            int  labelSpacing = 18;
            Rect rect         = new Rect(4, 0, 300, 20);

            if (showDebugInfo)
            {
                GUI.Label(rect, "Pooled Chunks: " + chunkPool.Count);
                rect.y += labelSpacing;
                GUI.Label(rect, "Pooled Chunk GameObjects: " + Chunk.chunkGameObjectPool.Count);
                rect.y += labelSpacing;
                GUI.Label(rect, "Chunks Loaded: " + chunkMap.Count);
                rect.y += labelSpacing;
                GUI.Label(rect, "Chunk Queue: " + chunkQueue.Count);
                rect.y += labelSpacing;
                GUI.Label(rect, "Chunk Mesh Queue: " + chunkMeshQueue.Count);
                rect.y += labelSpacing;
                GUI.Label(rect, "Meshes Last Frame: " + meshesLastFrame);
                rect.y += labelSpacing;
                GUI.Label(rect, "Update Time Last Frame: " + updateTimerLastFrame + "ms");
                rect.y += labelSpacing;
                GUI.Label(rect, "Thread Count: " + threadCount);
                rect.y += labelSpacing;
                GUI.Label(rect, "FPS: " + string.Format("{0:0.0}", averageFPS));
            }

            rect         = new Rect(Screen.width - 172, 2, 170, 20);
            labelSpacing = 22;

            if (GUI.Button(rect, "Grass Hills"))
            {
                terrainGenerator = FindObjectOfType <TerrainGenerator_GrassLand>();
                ResetAll();
            }
            rect.y += labelSpacing;

            if (GUI.Button(rect, "Alien Planet"))
            {
                terrainGenerator = FindObjectOfType <TerrainGenerator_AlienPlanet>();
                ResetAll();
            }
            rect.y += labelSpacing;

            if (GUI.Button(rect, "Cracked Surface"))
            {
                terrainGenerator = FindObjectOfType <TerrainGenerator_CrackedSurface>();
                ResetAll();
            }
            rect.y += labelSpacing;

            if (GUI.Button(rect, "Desert (SIMD)"))
            {
                terrainGenerator = FindObjectOfType <TerrainGeneratorSIMD_Desert>();
                ResetAll();
            }
            rect.y += labelSpacing;

            if (GUI.Button(rect, "Floating Islands (SIMD)"))
            {
                terrainGenerator = FindObjectOfType <TerrainGeneratorSIMD_FloatingIslands>();
                ResetAll();
            }
            rect.y += labelSpacing;

            if (GUI.Button(rect, "Caves (SIMD)"))
            {
                terrainGenerator = FindObjectOfType <TerrainGeneratorSIMD_Caves>();
                ResetAll(true);
            }
        }
Пример #3
0
        private static Mesh GradientMesh()
        {
            TerrainGeneratorBase terrainGenerator = chunk.voxelEngineManager.terrainGenerator;
            int index = -Chunk.VOXEL_STEP_X - Chunk.VOXEL_STEP_Y - Chunk.VOXEL_STEP_Z - 1;

            for (int x = -1; x < Chunk.SIZE - 1; x++)
            {
                for (int y = -1; y < Chunk.SIZE - 1; y++)
                {
                    for (int z = -1; z < Chunk.SIZE - 1; z++)
                    {
                        Voxel voxel, left, down, back;
                        int   adjIndex = -1;

                        if (x == -1 || y == -1 || z == -1)
                        {
                            voxel = GetAdjVoxel(++index, x, y, z);
                            left  = GetAdjVoxel(index - Chunk.VOXEL_STEP_X, x - 1, y, z);
                            down  = GetAdjVoxel(index - Chunk.VOXEL_STEP_Y, x, y - 1, z);
                            back  = GetAdjVoxel(index - Chunk.VOXEL_STEP_Z, x, y, z - 1);
                        }
                        else
                        {
                            voxel = chunk.voxelData[++index];
                            left  = GetAdjVoxelLeft(index, x);
                            down  = GetAdjVoxelDown(index, y);
                            back  = GetAdjVoxelBack(index, z);
                        }

                        if (voxel.IsSolid())
                        {
                            Color32 color     = new Color32();
                            bool    colorInit = false;

                            // Left
                            if (!left.IsSolid())
                            {
                                colorInit = true;
                                color     = terrainGenerator.DensityColor(voxel);

                                if (adjIndex == -1)
                                {
                                    adjIndex = AdjIndex(x, y, z);
                                }

                                Quad q = new Quad(
                                    adjIndex,
                                    adjIndex + ADJ_VOXEL_STEP_Z,
                                    adjIndex + ADJ_VOXEL_STEP_Y + ADJ_VOXEL_STEP_Z,
                                    adjIndex + ADJ_VOXEL_STEP_Y,
                                    color);

                                if (!gradientVerts.ContainsKey(q.i0))
                                {
                                    gradientVerts[q.i0] = new Vector3(x - 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x - 1, y - 1, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i1))
                                {
                                    gradientVerts[q.i1] = new Vector3(x - 0.5f, y - 0.5f, z + 0.5f) + VoxelGradient(x - 1, y - 1, z);
                                }
                                if (!gradientVerts.ContainsKey(q.i2))
                                {
                                    gradientVerts[q.i2] = new Vector3(x - 0.5f, y + 0.5f, z + 0.5f) + VoxelGradient(x - 1, y, z);
                                }
                                if (!gradientVerts.ContainsKey(q.i3))
                                {
                                    gradientVerts[q.i3] = new Vector3(x - 0.5f, y + 0.5f, z - 0.5f) + VoxelGradient(x - 1, y, z - 1);
                                }

                                quads.Add(q);
                            }

                            // Down
                            if (!down.IsSolid())
                            {
                                if (!colorInit)
                                {
                                    colorInit = true;
                                    color     = terrainGenerator.DensityColor(voxel);
                                }

                                if (adjIndex == -1)
                                {
                                    adjIndex = AdjIndex(x, y, z);
                                }

                                Quad q = new Quad(
                                    adjIndex,
                                    adjIndex + ADJ_VOXEL_STEP_X,
                                    adjIndex + ADJ_VOXEL_STEP_X + ADJ_VOXEL_STEP_Z,
                                    adjIndex + ADJ_VOXEL_STEP_Z,
                                    color);

                                if (!gradientVerts.ContainsKey(q.i0))
                                {
                                    gradientVerts[q.i0] = new Vector3(x - 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x - 1, y - 1, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i1))
                                {
                                    gradientVerts[q.i1] = new Vector3(x + 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x, y - 1, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i2))
                                {
                                    gradientVerts[q.i2] = new Vector3(x + 0.5f, y - 0.5f, z + 0.5f) + VoxelGradient(x, y - 1, z);
                                }
                                if (!gradientVerts.ContainsKey(q.i3))
                                {
                                    gradientVerts[q.i3] = new Vector3(x - 0.5f, y - 0.5f, z + 0.5f) + VoxelGradient(x - 1, y - 1, z);
                                }

                                quads.Add(q);
                            }

                            // Back
                            if (!back.IsSolid())
                            {
                                if (!colorInit)
                                {
                                    color = terrainGenerator.DensityColor(voxel);
                                }

                                if (adjIndex == -1)
                                {
                                    adjIndex = AdjIndex(x, y, z);
                                }

                                Quad q = new Quad(
                                    adjIndex,
                                    adjIndex + ADJ_VOXEL_STEP_Y,
                                    adjIndex + ADJ_VOXEL_STEP_X + ADJ_VOXEL_STEP_Y,
                                    adjIndex + ADJ_VOXEL_STEP_X,
                                    color);

                                if (!gradientVerts.ContainsKey(q.i0))
                                {
                                    gradientVerts[q.i0] = new Vector3(x - 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x - 1, y - 1, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i1))
                                {
                                    gradientVerts[q.i1] = new Vector3(x - 0.5f, y + 0.5f, z - 0.5f) + VoxelGradient(x - 1, y, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i2))
                                {
                                    gradientVerts[q.i2] = new Vector3(x + 0.5f, y + 0.5f, z - 0.5f) + VoxelGradient(x, y, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i3))
                                {
                                    gradientVerts[q.i3] = new Vector3(x + 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x, y - 1, z - 1);
                                }

                                quads.Add(q);
                            }
                        }
                        else                         // Voxel not solid
                        {
                            // Left
                            if (left.IsSolid())
                            {
                                if (adjIndex == -1)
                                {
                                    adjIndex = AdjIndex(x, y, z);
                                }

                                Quad q = new Quad(
                                    adjIndex + ADJ_VOXEL_STEP_Y,
                                    adjIndex + ADJ_VOXEL_STEP_Y + ADJ_VOXEL_STEP_Z,
                                    adjIndex + ADJ_VOXEL_STEP_Z,
                                    adjIndex,
                                    terrainGenerator.DensityColor(left));

                                if (!gradientVerts.ContainsKey(q.i0))
                                {
                                    gradientVerts[q.i0] = new Vector3(x - 0.5f, y + 0.5f, z - 0.5f) + VoxelGradient(x - 1, y, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i1))
                                {
                                    gradientVerts[q.i1] = new Vector3(x - 0.5f, y + 0.5f, z + 0.5f) + VoxelGradient(x - 1, y, z);
                                }
                                if (!gradientVerts.ContainsKey(q.i2))
                                {
                                    gradientVerts[q.i2] = new Vector3(x - 0.5f, y - 0.5f, z + 0.5f) + VoxelGradient(x - 1, y - 1, z);
                                }
                                if (!gradientVerts.ContainsKey(q.i3))
                                {
                                    gradientVerts[q.i3] = new Vector3(x - 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x - 1, y - 1, z - 1);
                                }

                                quads.Add(q);
                            }

                            // Down
                            if (down.IsSolid())
                            {
                                if (adjIndex == -1)
                                {
                                    adjIndex = AdjIndex(x, y, z);
                                }

                                Quad q = new Quad(
                                    adjIndex + ADJ_VOXEL_STEP_Z,
                                    adjIndex + ADJ_VOXEL_STEP_X + ADJ_VOXEL_STEP_Z,
                                    adjIndex + ADJ_VOXEL_STEP_X,
                                    adjIndex,
                                    terrainGenerator.DensityColor(down));

                                if (!gradientVerts.ContainsKey(q.i0))
                                {
                                    gradientVerts[q.i0] = new Vector3(x - 0.5f, y - 0.5f, z + 0.5f) + VoxelGradient(x - 1, y - 1, z);
                                }
                                if (!gradientVerts.ContainsKey(q.i1))
                                {
                                    gradientVerts[q.i1] = new Vector3(x + 0.5f, y - 0.5f, z + 0.5f) + VoxelGradient(x, y - 1, z);
                                }
                                if (!gradientVerts.ContainsKey(q.i2))
                                {
                                    gradientVerts[q.i2] = new Vector3(x + 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x, y - 1, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i3))
                                {
                                    gradientVerts[q.i3] = new Vector3(x - 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x - 1, y - 1, z - 1);
                                }

                                quads.Add(q);
                            }

                            // Back
                            if (back.IsSolid())
                            {
                                if (adjIndex == -1)
                                {
                                    adjIndex = AdjIndex(x, y, z);
                                }

                                Quad q = new Quad(
                                    adjIndex + ADJ_VOXEL_STEP_X,
                                    adjIndex + ADJ_VOXEL_STEP_X + ADJ_VOXEL_STEP_Y,
                                    adjIndex + ADJ_VOXEL_STEP_Y,
                                    adjIndex,
                                    terrainGenerator.DensityColor(back));

                                if (!gradientVerts.ContainsKey(q.i0))
                                {
                                    gradientVerts[q.i0] = new Vector3(x + 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x, y - 1, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i1))
                                {
                                    gradientVerts[q.i1] = new Vector3(x + 0.5f, y + 0.5f, z - 0.5f) + VoxelGradient(x, y, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i2))
                                {
                                    gradientVerts[q.i2] = new Vector3(x - 0.5f, y + 0.5f, z - 0.5f) + VoxelGradient(x - 1, y, z - 1);
                                }
                                if (!gradientVerts.ContainsKey(q.i3))
                                {
                                    gradientVerts[q.i3] = new Vector3(x - 0.5f, y - 0.5f, z - 0.5f) + VoxelGradient(x - 1, y - 1, z - 1);
                                }

                                quads.Add(q);
                            }
                        }
                    }
                }
            }

            if (quads.Count == 0)
            {
                return(null);
            }

            Vector3[] verts = new Vector3[quads.Count * 4];
            //Vector2[] uvs = new Vector2[quads.Count * 4];
            Color32[] colors = new Color32[quads.Count * 4];
            int[]     tris   = new int[quads.Count * 6];

            int vertIndex = 0;
            int triIndex  = 0;

            foreach (Quad quad in quads)
            {
                colors[vertIndex]  = quad.color;
                verts[vertIndex++] = gradientVerts[quad.i0];
                colors[vertIndex]  = quad.color;
                verts[vertIndex++] = gradientVerts[quad.i1];
                colors[vertIndex]  = quad.color;
                verts[vertIndex++] = gradientVerts[quad.i2];
                colors[vertIndex]  = quad.color;
                verts[vertIndex++] = gradientVerts[quad.i3];

                if ((verts[vertIndex - 4] - verts[vertIndex - 2]).sqrMagnitude <
                    (verts[vertIndex - 3] - verts[vertIndex - 1]).sqrMagnitude)
                {
                    tris[triIndex++] = vertIndex - 4;
                    tris[triIndex++] = vertIndex - 3;
                    tris[triIndex++] = vertIndex - 2;
                    tris[triIndex++] = vertIndex - 4;
                    tris[triIndex++] = vertIndex - 2;
                    tris[triIndex++] = vertIndex - 1;
                }
                else
                {
                    tris[triIndex++] = vertIndex - 3;
                    tris[triIndex++] = vertIndex - 2;
                    tris[triIndex++] = vertIndex - 1;
                    tris[triIndex++] = vertIndex - 3;
                    tris[triIndex++] = vertIndex - 1;
                    tris[triIndex++] = vertIndex - 4;
                }
            }

            Mesh mesh = new Mesh
            {
                vertices  = verts,
                triangles = tris,
                colors32  = colors
            };

            mesh.RecalculateNormals();

            return(mesh);
        }
Пример #4
0
        private static Mesh BasicMesh()
        {
            TerrainGeneratorBase terrainGenerator = chunk.voxelEngineManager.terrainGenerator;
            int index = -1;

            for (int x = 0; x < Chunk.SIZE; x++)
            {
                for (int y = 0; y < Chunk.SIZE; y++)
                {
                    for (int z = 0; z < Chunk.SIZE; z++)
                    {
                        Voxel voxel = chunk.voxelData[++index];
                        Voxel left  = GetAdjVoxelLeft(index, x);
                        Voxel down  = GetAdjVoxelDown(index, y);
                        Voxel back  = GetAdjVoxelBack(index, z);

                        if (voxel.IsSolid())
                        {
                            Color32 color     = new Color32();
                            bool    colorInit = false;

                            // Left
                            if (!left.IsSolid())
                            {
                                colorInit = true;
                                color     = terrainGenerator.DensityColor(voxel);

                                quads.Add(new Quad(
                                              new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                              new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                              new Vector3(x - 0.5f, y + 0.5f, z + 0.5f),
                                              new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                              color, Direction.Left));
                            }

                            // Down
                            if (!down.IsSolid())
                            {
                                if (!colorInit)
                                {
                                    colorInit = true;
                                    color     = terrainGenerator.DensityColor(voxel);
                                }

                                quads.Add(new Quad(
                                              new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                              new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                              new Vector3(x + 0.5f, y - 0.5f, z + 0.5f),
                                              new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                              color, Direction.Down));
                            }

                            // Back
                            if (!back.IsSolid())
                            {
                                if (!colorInit)
                                {
                                    color = terrainGenerator.DensityColor(voxel);
                                }

                                quads.Add(new Quad(
                                              new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                              new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                              new Vector3(x + 0.5f, y + 0.5f, z - 0.5f),
                                              new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                              color, Direction.Back));
                            }
                        }
                        else                         // Voxel not solid
                        {
                            // Left
                            if (left.IsSolid())
                            {
                                quads.Add(new Quad(
                                              new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                              new Vector3(x - 0.5f, y + 0.5f, z + 0.5f),
                                              new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                              new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                              terrainGenerator.DensityColor(left), Direction.Right));
                            }

                            // Down
                            if (down.IsSolid())
                            {
                                quads.Add(new Quad(
                                              new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                              new Vector3(x + 0.5f, y - 0.5f, z + 0.5f),
                                              new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                              new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                              terrainGenerator.DensityColor(down), Direction.Up));
                            }

                            // Back
                            if (back.IsSolid())
                            {
                                quads.Add(new Quad(
                                              new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                              new Vector3(x + 0.5f, y + 0.5f, z - 0.5f),
                                              new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                              new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                              terrainGenerator.DensityColor(back), Direction.Forward));
                            }
                        }
                    }
                }
            }

            if (quads.Count == 0)
            {
                return(null);
            }

            Vector3[] verts   = new Vector3[quads.Count * 4];
            Vector3[] normals = new Vector3[quads.Count * 4];
            //Vector2[] uvs = new Vector2[quads.Count * 4];
            Color32[] colors = new Color32[quads.Count * 4];
            int[]     tris   = new int[quads.Count * 6];

            int vertIndex = 0;
            int triIndex  = 0;

            foreach (Quad quad in quads)
            {
                tris[triIndex++] = vertIndex;
                tris[triIndex++] = vertIndex + 1;
                tris[triIndex++] = vertIndex + 2;
                tris[triIndex++] = vertIndex;
                tris[triIndex++] = vertIndex + 2;
                tris[triIndex++] = vertIndex + 3;

                colors[vertIndex]  = quad.color;
                normals[vertIndex] = directionNormals[(int)quad.direction];
                verts[vertIndex++] = quad.v0;
                colors[vertIndex]  = quad.color;
                normals[vertIndex] = directionNormals[(int)quad.direction];
                verts[vertIndex++] = quad.v1;
                colors[vertIndex]  = quad.color;
                normals[vertIndex] = directionNormals[(int)quad.direction];
                verts[vertIndex++] = quad.v2;
                colors[vertIndex]  = quad.color;
                normals[vertIndex] = directionNormals[(int)quad.direction];
                verts[vertIndex++] = quad.v3;
            }

            Mesh mesh = new Mesh
            {
                vertices  = verts,
                normals   = normals,
                triangles = tris,
                colors32  = colors
            };

            return(mesh);
        }
Пример #5
0
        private static Mesh AmbientOcclusionMesh()
        {
            TerrainGeneratorBase terrainGenerator = chunk.voxelEngineManager.terrainGenerator;
            int index = -Chunk.VOXEL_STEP_X - Chunk.VOXEL_STEP_Y - Chunk.VOXEL_STEP_Z - 1;

            for (int x = -1; x < Chunk.SIZE - 1; x++)
            {
                for (int y = -1; y < Chunk.SIZE - 1; y++)
                {
                    for (int z = -1; z < Chunk.SIZE - 1; z++)
                    {
                        Voxel voxel;
                        Voxel left;
                        Voxel down;
                        Voxel back;

                        if (x == -1 || y == -1 || z == -1)
                        {
                            voxel = GetAdjVoxel(++index, x, y, z);
                            left  = GetAdjVoxel(index - Chunk.VOXEL_STEP_X, x - 1, y, z);
                            down  = GetAdjVoxel(index - Chunk.VOXEL_STEP_Y, x, y - 1, z);
                            back  = GetAdjVoxel(index - Chunk.VOXEL_STEP_Z, x, y, z - 1);
                        }
                        else
                        {
                            voxel = chunk.voxelData[++index];
                            left  = GetAdjVoxelLeft(index, x);
                            down  = GetAdjVoxelDown(index, y);
                            back  = GetAdjVoxelBack(index, z);
                        }

                        if (voxel.IsSolid())
                        {
                            Color32 color     = new Color32();
                            bool    colorInit = false;

                            // Left
                            if (!left.IsSolid())
                            {
                                colorInit = true;
                                color     = terrainGenerator.DensityColor(voxel);

                                Quad q = new Quad(
                                    new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                    new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                    new Vector3(x - 0.5f, y + 0.5f, z + 0.5f),
                                    new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                    color, Direction.Left);

                                q.i0 = LightLevelX(q.v0, color, y, z, -0.25f);
                                q.i1 = LightLevelX(q.v1, color, y, z, -0.25f);
                                q.i2 = LightLevelX(q.v2, color, y, z, -0.25f);
                                q.i3 = LightLevelX(q.v3, color, y, z, -0.25f);

                                quads.Add(q);
                            }

                            // Down
                            if (!down.IsSolid())
                            {
                                if (!colorInit)
                                {
                                    colorInit = true;
                                    color     = terrainGenerator.DensityColor(voxel);
                                }

                                Quad q = new Quad(
                                    new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                    new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                    new Vector3(x + 0.5f, y - 0.5f, z + 0.5f),
                                    new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                    color, Direction.Down);

                                q.i0 = LightLevelY(q.v0, color, x, z, -0.25f);
                                q.i1 = LightLevelY(q.v1, color, x, z, -0.25f);
                                q.i2 = LightLevelY(q.v2, color, x, z, -0.25f);
                                q.i3 = LightLevelY(q.v3, color, x, z, -0.25f);

                                quads.Add(q);
                            }

                            // Back
                            if (!back.IsSolid())
                            {
                                if (!colorInit)
                                {
                                    color = terrainGenerator.DensityColor(voxel);
                                }

                                Quad q = new Quad(
                                    new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                    new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                    new Vector3(x + 0.5f, y + 0.5f, z - 0.5f),
                                    new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                    color, Direction.Back);

                                q.i0 = LightLevelZ(q.v0, color, x, y, -0.25f);
                                q.i1 = LightLevelZ(q.v1, color, x, y, -0.25f);
                                q.i2 = LightLevelZ(q.v2, color, x, y, -0.25f);
                                q.i3 = LightLevelZ(q.v3, color, x, y, -0.25f);

                                quads.Add(q);
                            }
                        }
                        else                         // Voxel not solid
                        {
                            // Left
                            if (left.IsSolid())
                            {
                                Quad q = new Quad(
                                    new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                    new Vector3(x - 0.5f, y + 0.5f, z + 0.5f),
                                    new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                    new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                    terrainGenerator.DensityColor(left), Direction.Right);

                                q.i0 = LightLevelX(q.v0, q.color, y, z, 0.25f);
                                q.i1 = LightLevelX(q.v1, q.color, y, z, 0.25f);
                                q.i2 = LightLevelX(q.v2, q.color, y, z, 0.25f);
                                q.i3 = LightLevelX(q.v3, q.color, y, z, 0.25f);

                                quads.Add(q);
                            }

                            // Down
                            if (down.IsSolid())
                            {
                                Quad q = new Quad(
                                    new Vector3(x - 0.5f, y - 0.5f, z + 0.5f),
                                    new Vector3(x + 0.5f, y - 0.5f, z + 0.5f),
                                    new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                    new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                    terrainGenerator.DensityColor(down), Direction.Up);

                                q.i0 = LightLevelY(q.v0, q.color, x, z, 0.25f);
                                q.i1 = LightLevelY(q.v1, q.color, x, z, 0.25f);
                                q.i2 = LightLevelY(q.v2, q.color, x, z, 0.25f);
                                q.i3 = LightLevelY(q.v3, q.color, x, z, 0.25f);

                                quads.Add(q);
                            }

                            // Back
                            if (back.IsSolid())
                            {
                                Quad q = new Quad(
                                    new Vector3(x + 0.5f, y - 0.5f, z - 0.5f),
                                    new Vector3(x + 0.5f, y + 0.5f, z - 0.5f),
                                    new Vector3(x - 0.5f, y + 0.5f, z - 0.5f),
                                    new Vector3(x - 0.5f, y - 0.5f, z - 0.5f),
                                    terrainGenerator.DensityColor(back), Direction.Forward);

                                q.i0 = LightLevelZ(q.v0, q.color, x, y, 0.25f);
                                q.i1 = LightLevelZ(q.v1, q.color, x, y, 0.25f);
                                q.i2 = LightLevelZ(q.v2, q.color, x, y, 0.25f);
                                q.i3 = LightLevelZ(q.v3, q.color, x, y, 0.25f);

                                quads.Add(q);
                            }
                        }
                    }
                }
            }

            if (quads.Count == 0)
            {
                return(null);
            }

            Vector3[] verts   = new Vector3[quads.Count * 4];
            Vector3[] normals = new Vector3[quads.Count * 4];
            //Vector2[] uvs = new Vector2[quads.Count * 4];
            Color32[] colors = new Color32[quads.Count * 4];
            int[]     tris   = new int[quads.Count * 6];

            int vertIndex = 0;
            int triIndex  = 0;

            foreach (Quad quad in quads)
            {
                if (quad.i0 + quad.i2 < quad.i1 + quad.i3)
                {
                    tris[triIndex++] = vertIndex;
                    tris[triIndex++] = vertIndex + 1;
                    tris[triIndex++] = vertIndex + 2;
                    tris[triIndex++] = vertIndex;
                    tris[triIndex++] = vertIndex + 2;
                    tris[triIndex++] = vertIndex + 3;
                }
                else
                {
                    tris[triIndex++] = vertIndex + 1;
                    tris[triIndex++] = vertIndex + 2;
                    tris[triIndex++] = vertIndex + 3;
                    tris[triIndex++] = vertIndex + 1;
                    tris[triIndex++] = vertIndex + 3;
                    tris[triIndex++] = vertIndex;
                }

                normals[vertIndex] = directionNormals[(int)quad.direction];
                colors[vertIndex]  = LightColorAdjust(quad.color, quad.i0);
                verts[vertIndex++] = quad.v0;
                normals[vertIndex] = directionNormals[(int)quad.direction];
                colors[vertIndex]  = LightColorAdjust(quad.color, quad.i1);
                verts[vertIndex++] = quad.v1;
                normals[vertIndex] = directionNormals[(int)quad.direction];
                colors[vertIndex]  = LightColorAdjust(quad.color, quad.i2);
                verts[vertIndex++] = quad.v2;
                normals[vertIndex] = directionNormals[(int)quad.direction];
                colors[vertIndex]  = LightColorAdjust(quad.color, quad.i3);
                verts[vertIndex++] = quad.v3;
            }

            Mesh mesh = new Mesh
            {
                vertices  = verts,
                normals   = normals,
                triangles = tris,
                colors32  = colors
            };

            return(mesh);
        }