public void Build(TerrainController controller, int chunkX, int chunkY) { isBuilt = false; _chunkX = chunkX; _chunkY = chunkY; _terrainController = controller; var currentTransform = transform; currentTransform.position = new Vector3(chunkX * (_terrainController.terrainGeneratorSettings.size - 1) * _terrainController.terrainGeneratorSettings.gridSize, 0, chunkY * (_terrainController.terrainGeneratorSettings.size - 1) * _terrainController.terrainGeneratorSettings.gridSize); currentTransform.name = "chunk (" + chunkX + " " + chunkY + ")"; StartCoroutine(BuildMesh()); }
public static IEnumerator GetChunkData(IntegerCoordinate2D coordinate2D, TerrainController controller, TerrainTile tile) { //Working = true; var settings = controller.terrainGeneratorSettings; var shader = settings.terrainComputeShader; //Debug.Log("Starting GPU Compute "+Time.frameCount); var dataSize = settings.size + 2; var kernel1 = settings.terrainComputeShader.FindKernel("TerrainGeneratorPass1"); var kernel2 = settings.terrainComputeShader.FindKernel("TerrainGeneratorPass2"); if (_inputData == null || _inputData.Length != dataSize * dataSize) { _inputData = new TerrainTileVertexData[dataSize * dataSize]; _dataBuffer = new ComputeBuffer(_inputData.Length, 24); //2 * Vector3 = 2 * (3 * float) = 2 * (3 * 4) = 24 _dataBuffer.SetData(_inputData); shader.SetInt("_size", dataSize); TerrainUtilities.TransferTerrainGeneratorSettingsToComputeShader(shader, settings); shader.SetBuffer(kernel1, "_Data", _dataBuffer); shader.SetBuffer(kernel2, "_Data", _dataBuffer); shader.SetFloat("_BlendExponent", controller.blendExponent); shader.SetFloat("_BlendOffset", controller.blendOffset); shader.SetVectorArray("_maxTessellationStrengths", controller.materialData.GetMaxTessellationStrengthArray()); } //Debug.Log("StartX: "+coordinate2D.x * (settings.size - 1)); settings.terrainComputeShader.SetInt("_startX", coordinate2D.x * (settings.size - 1)); settings.terrainComputeShader.SetInt("_startY", coordinate2D.y * (settings.size - 1)); //Init splat RenderTexture var splatTexture = new RenderTexture(dataSize, dataSize, 0) { enableRandomWrite = true, useMipMap = true, filterMode = FilterMode.Bilinear }; splatTexture.Create(); settings.terrainComputeShader.SetTexture(kernel2, "_splatTexture", splatTexture); /*if (tile.data.tessellationTexture != null) * { * Object.Destroy(tile.data.tessellationTexture); * }*/ //Init tessellation Texture var tessellationTexture = new RenderTexture(dataSize, dataSize, 0) { enableRandomWrite = true, useMipMap = true, filterMode = FilterMode.Point }; tessellationTexture.Create(); settings.terrainComputeShader.SetTexture(kernel2, "_tessellationTexture", tessellationTexture); settings.terrainComputeShader.Dispatch(kernel1, dataSize * dataSize / 8, 1, 1); settings.terrainComputeShader.Dispatch(kernel2, dataSize * dataSize / 8, 1, 1); var request = AsyncGPUReadback.Request(_dataBuffer); yield return(new WaitUntil(() => request.done)); _inputData = request.GetData <TerrainTileVertexData>().ToArray(); //Combine all data into output struct tile.data = new TerrainTileData { locationData = _inputData//, splatTexture = splatTexture, tessellationTexture = tessellationTexture }; yield return(null); }
public static IEnumerator GetChunkData(IntegerCoordinate2D coordinate2D, TerrainController controller, TerrainTile tile) { var settings = controller.terrainGeneratorSettings; var dataSize = settings.size + 2; var data = new TerrainTileVertexData[dataSize * dataSize]; var colors = new Color[settings.size * settings.size]; for (var x = 0; x < dataSize; x++) { for (var y = 0; y < dataSize; y++) { var position = new Vector2((x - 1 + coordinate2D.x * (settings.size - 1)) * settings.gridSize, (y - 1 + coordinate2D.y * (settings.size - 1)) * settings.gridSize); var h1 = Perlin(position, settings.offset, settings.scale1, settings.pow1) * Perlin(position, settings.offset, settings.scale2, settings.pow2) * settings.height1; var h3 = Perlin(position, settings.offset, settings.scale3, settings.pow3) * settings.height3; var h4 = 0.5f * (Perlin(position, settings.offset, settings.scale4, settings.pow4) + Perlin(position, settings.offset, settings.scale4 * 2, settings.pow4)) * settings.height4; var h5 = Perlin(position, settings.offset, settings.scale5, settings.pow5) * settings.height5; var mul1 = Perlin(position, settings.offset, settings.scale6, settings.pow6); var mul2 = Perlin(position, settings.offset, settings.scale7, settings.pow7) * settings.weightMultiplier2; var height = (h1 + h3 + h4 + h5) * (1 + (mul1 + mul2) / (1 + settings.weightMultiplier2) * settings.multiplierScale); var maxHeight = settings.height1 + settings.height3 + settings.height4 + settings.height5; var sandStrength = BlendSplat(1 - height / maxHeight + Perlin(position, settings.offset, settings.scale4 * 2, settings.pow4) * settings.sandRandom, settings.sandBlend, 0.99f); var snowStrength = (1 - sandStrength) * BlendSplat(height / maxHeight + Perlin(position, settings.offset, settings.scale4 * 2, settings.pow4) * settings.snowRandom, settings.snowBlend, 0.6f); var temperature = BlendSplat((Perlin(position, settings.offset, settings.temperatureScale, 1) * ((1 + (Perlin(position, settings.offset, settings.temperatureScale * 20, 1) - 0.5f) * settings.temperatureRandom))), settings.temperatureBlend, 0.5f); var remainingStrength = (1 - (snowStrength + sandStrength)); data[x + dataSize * y].position = new Vector3((x - 1) * settings.gridSize, height, (y - 1) * settings.gridSize); if (x > 0 && y > 0 && x < settings.size + 1 && y < settings.size + 1) { colors[(x - 1) + settings.size * (y - 1)] = new Color(remainingStrength * temperature, remainingStrength * (1 - temperature), sandStrength, snowStrength); } } } //Calculate Normals... for (var x = 0; x < settings.size; x++) { for (var y = 0; y < settings.size; y++) { var l = data[(x + 0) + dataSize * (y + 1)].position.y; var r = data[(x + 2) + dataSize * (y + 1)].position.y; var b = data[(x + 1) + dataSize * (y + 0)].position.y; var t = data[(x + 1) + dataSize * (y + 2)].position.y; var dx = 2 * (r - l); var dy = 2 * (t - b); var up = -4.0f * settings.gridSize; data[(x + 1) + dataSize * (y + 1)].normal = -(new Vector3(dx, up, dy) * 0.25f).normalized; } } for (var x = 0; x < settings.size; x++) { for (var y = 0; y < settings.size; y++) { var splat = colors[x + settings.size * y]; var normal = data[(x + 1) + dataSize * (y + 1)].normal; var tessellationStrength = GetTessellationStrength(splat, normal, controller.blendOffset, controller.blendExponent, controller.materialData.GetMaxTessellationStrengthArray()); //Debug.Log(tessellationStrength); data[(x + 1) + dataSize * (y + 1)].tessellationStrength = new Vector2(tessellationStrength, 0); } } tile.data = new TerrainTileData { locationData = data, splats = colors }; yield return(null); }