Esempio n. 1
0
        /// <summary>
        /// Computes normal vectors based on weight of each voxel.
        /// </summary>
        /// <param name="voxels">Array of voxels.</param>
        private void ComputeNormal(Voxel[, ,] voxels)
        {
            int width = voxels.GetLength(0);
            int height = voxels.GetLength(1);
            int depth = voxels.GetLength(2);

            Parallel.For(0, width, (x) =>
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        int xi = x == width - 1 ? x : x + 1;
                        int xd = x == 0 ? x : x - 1;

                        int yi = y == height - 1 ? y : y + 1;
                        int yd = y == 0 ? y : y - 1;

                        int zi = z == depth - 1 ? z : z + 1;
                        int zd = z == 0 ? z : z - 1;

                        Vector3 normal = new Vector3()
                        {
                            X = voxels[xi, y, z].Weight - voxels[xd, y, z].Weight,
                            Y = voxels[x, yi, z].Weight - voxels[x, yd, z].Weight,
                            Z = voxels[x, y, zi].Weight - voxels[x, y, zd].Weight
                        };

                        normal = -normal;
                        normal.Normalize();

                        voxels[x, y, z].Normal = normal;
                    }
                }
            });
        }
Esempio n. 2
0
        /// <summary>
        /// Computes triangle positions and normal vectors based on array of voxels.
        /// </summary>
        /// <param name="voxels">Array of voxels.</param>
        /// <param name="levelOfDetail">Lower value makes more triangles.</param>
        /// <returns>List of triangles.</returns>
        private List<VoxelMeshVertex> ComputeTriangles(Voxel[, ,] voxels, int levelOfDetail)
        {
            List<VoxelMeshVertex> triangles = new List<VoxelMeshVertex>();

            for (int x = 0; x < voxels.GetLength(0) - levelOfDetail; x += levelOfDetail)
            {
                for (int y = 0; y < voxels.GetLength(1) - levelOfDetail; y += levelOfDetail)
                {
                    for (int z = 0; z < voxels.GetLength(2) - levelOfDetail; z += levelOfDetail)
                    {
                        Voxel[] cubeVoxels = new Voxel[]
						{
						   voxels[x, y, z],
						   voxels[x, y, z + levelOfDetail],
						   voxels[x + levelOfDetail, y, z + levelOfDetail],
						   voxels[x + levelOfDetail, y, z],
						   voxels[x, y + levelOfDetail, z],
						   voxels[x, y + levelOfDetail, z + levelOfDetail],
						   voxels[x + levelOfDetail, y + levelOfDetail, z + levelOfDetail],
						   voxels[x + levelOfDetail, y + levelOfDetail, z]
						};

                        triangles.AddRange(VoxelCube.ComputeTriangles(cubeVoxels));
                    }
                }
            }

            return triangles;
        }
Esempio n. 3
0
        /// <summary>
        /// Computes ambient color for each voxel.
        /// </summary>
        /// <param name="voxels">Array of voxels.</param>
        private void ComputeAmbient(Voxel[, ,] voxels)
        {
            int width = voxels.GetLength(0);
            int height = voxels.GetLength(1);
            int depth = voxels.GetLength(2);

            float stepLength = (width * container.Settings.AmbientRayWidth / 100.0f) / container.Settings.AmbientSamplesCount;

            Parallel.For(0, width, (x) =>
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        float ambient = 0;
                        Vector3 position = voxels[x, y, z].Position;

                        for (int i = 0; i < poissonDisc.Length; i++)
                        {
                            float sample = 0;

                            for (int j = 0; j < container.Settings.AmbientSamplesCount; j++)
                            {
                                // Ray starting point is situated in a small distance from center to avoid rendering artifacts.
                                int stepNumber = j + 2;

                                int cx = (int)Helper.Clamp(position.X + stepNumber * stepLength * poissonDisc[i].X, 0, width - 1);
                                int cy = (int)Helper.Clamp(position.Y + stepNumber * stepLength * poissonDisc[i].Y, 0, height - 1);
                                int cz = (int)Helper.Clamp(position.Z + stepNumber * stepLength * poissonDisc[i].Z, 0, depth - 1);

                                sample += voxels[cx, cy, cz].Weight > 0 ? 0 : 1;
                            }

                            ambient += sample / container.Settings.AmbientSamplesCount;
                        }

                        voxels[x, y, z].Ambient = ambient / poissonDisc.Length;
                    }
                }
            });
        }