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