Esempio n. 1
0
        public static Brush CreateBrush(ErosionParametersComponent erosionParameters, int mapSize)
        {
            var erosionBrushRadius       = erosionParameters.ErosionBrushRadius;
            var erosionBrushRadiusSquare = erosionBrushRadius * erosionBrushRadius;

            var brushIndexOffsets = new List <int>();
            var brushWeights      = new List <float>();
            var weightSum         = 0f;

            for (var brushY = -erosionBrushRadius; brushY <= erosionBrushRadius; brushY++)
            {
                for (var brushX = -erosionBrushRadius; brushX <= erosionBrushRadius; brushX++)
                {
                    var sqrDst = brushX * brushX + brushY * brushY;
                    if (sqrDst < erosionBrushRadiusSquare)
                    {
                        brushIndexOffsets.Add(brushY * mapSize + brushX);
                        var brushWeight = 1 - Mathf.Sqrt(sqrDst) / erosionBrushRadius;
                        weightSum += brushWeight;
                        brushWeights.Add(brushWeight);
                    }
                }
            }

            return(new Brush()
            {
                Weights = brushWeights.Select(weight => weight / weightSum).ToList(),
                IndexOffsets = brushIndexOffsets
            });
        }
Esempio n. 2
0
        private void ConstructMesh(
            MapInfoComponent mapInfo,
            MeshParametersComponent meshParameters,
            ErosionParametersComponent erosionParameters)
        {
            var mapSize     = meshParameters.MapResolution;
            var brushRadius = erosionParameters.ErosionBrushRadius;
            var verts       = new Vector3[mapSize * mapSize];
            var triangles   = new int[(mapSize - 1) * (mapSize - 1) * 6];

            for (var i = 0; i < mapSize * mapSize; i++)
            {
                var x = i % mapSize;
                var y = i / mapSize;
                var borderedMapIndex = (y + brushRadius) * mapInfo.MapSizeWithBorder + x + brushRadius;
                var meshMapIndex     = y * mapSize + x;

                var percent = new Vector2(x / (mapSize - 1f), y / (mapSize - 1f));
                var pos     = new Vector3(percent.x * 2 - 1, 0, percent.y * 2 - 1) * meshParameters.Scale;

                var normalizedHeight = mapInfo.Map[borderedMapIndex];
                pos += Vector3.up * normalizedHeight * meshParameters.ElevationScale;
                verts[meshMapIndex] = pos;

                if (ConstructMeshHelper.IsInside(mapSize, x, y))
                {
                    ConstructMeshHelper.ConstructTriangles(x, y, mapSize, meshMapIndex, triangles);
                }
            }

            if (mapInfo.Mesh == null)
            {
                mapInfo.Mesh = new Mesh();
            }
            else
            {
                mapInfo.Mesh.Clear();
            }

            mapInfo.Mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            mapInfo.Mesh.vertices    = verts;
            mapInfo.Mesh.triangles   = triangles;
            mapInfo.Mesh.RecalculateNormals();

            var(meshFilter, meshRenderer) = AssignMeshComponents();
            meshFilter.sharedMesh         = mapInfo.Mesh;
            meshRenderer.sharedMaterial   = meshParameters.Material;
        }
Esempio n. 3
0
        private void SetErosionParameters(
            ErosionParametersComponent erosionParameters, MapInfoComponent mapInfo, Brush brush)
        {
            var erosion = erosionParameters.Erosion;

            erosion.SetInt("borderSize", erosionParameters.ErosionBrushRadius);
            erosion.SetInt("mapSize", mapInfo.MapSizeWithBorder);
            erosion.SetInt("brushLength", brush.IndexOffsets.Count);
            erosion.SetInt("maxLifetime", erosionParameters.MaxLifetime);
            erosion.SetFloat("inertia", erosionParameters.Inertia);
            erosion.SetFloat("sedimentCapacityFactor", erosionParameters.SedimentCapacityFactor);
            erosion.SetFloat("minSedimentCapacity", erosionParameters.MinSedimentCapacity);
            erosion.SetFloat("depositSpeed", erosionParameters.DepositSpeed);
            erosion.SetFloat("erodeSpeed", erosionParameters.ErodeSpeed);
            erosion.SetFloat("evaporateSpeed", erosionParameters.EvaporateSpeed);
            erosion.SetFloat("gravity", erosionParameters.Gravity);
            erosion.SetFloat("startSpeed", erosionParameters.StartSpeed);
            erosion.SetFloat("startWater", erosionParameters.StartWater);
        }
Esempio n. 4
0
        private void Erode(
            ErosionParametersComponent erosionParameters,
            MeshParametersComponent meshParameters,
            MapInfoComponent mapInfo)
        {
            const int maxThreadCount = 65535;

            var brush       = GeneralHelper.CreateBrush(erosionParameters, meshParameters.MapResolution);
            var brushShader = new BrushShader()
            {
                IndexBuffer = GeneralHelper.GetBufferFor(brush.IndexOffsets, erosionParameters.Erosion,
                                                         "brushIndices"),
                WeightBuffer =
                    GeneralHelper.GetBufferFor(brush.Weights, erosionParameters.Erosion, "brushWeights")
            };
            var randomIndices = GeneralHelper.GenerateIndices(
                erosionParameters.ErosionIterationCount,
                erosionParameters.ErosionBrushRadius,
                meshParameters.MapResolution);
            var randomIndexBuffer = GeneralHelper.GetBufferFor(randomIndices, erosionParameters.Erosion, "randomIndices");
            var mapBuffer         = GeneralHelper.GetBufferFor(mapInfo.Map, erosionParameters.Erosion, "map");

            SetErosionParameters(erosionParameters, mapInfo, brush);

            erosionParameters.Erosion.Dispatch(
                0,
                Math.Min(erosionParameters.ErosionIterationCount / 1024, maxThreadCount),
                1,
                1);
            mapBuffer.GetData(mapInfo.Map);

            GeneralHelper.ReleaseBuffers(new List <ComputeBuffer>()
            {
                brushShader.IndexBuffer,
                brushShader.WeightBuffer,
                mapBuffer,
                randomIndexBuffer
            });
        }