public Vector4 SampleNoise(Vector2 xzPosition, AsyncTextureUnsafe <Color32> source, float strength, NoiseType type) { Vector4 normalizedNoise = RawTextureSampler.SampleBilinear( xzPosition.x * RenderConfig.NoiseScale, xzPosition.y * RenderConfig.NoiseScale, source ); if (type == NoiseType.NegativeOneToOne) { normalizedNoise.Set( normalizedNoise.x * 2f - 1f, normalizedNoise.y * 2f - 1f, normalizedNoise.z * 2f - 1f, normalizedNoise.w * 2f - 1f ); } return(normalizedNoise * strength); }
private IEnumerator RefreshHeightmap(ChunkOrientationData chunkOrientation) { var terrainData = Terrain.terrainData; var unsafeOrientationTexture = new AsyncTextureUnsafe <Color32>(chunkOrientation.OrientationTexture); var unsafeWeightsTexture = new AsyncTextureUnsafe <Color32>(chunkOrientation.WeightsTexture); var unsafeDuckTexture = new AsyncTextureUnsafe <Color32>(chunkOrientation.DuckTexture); var unsafeFlatlandsNoise = new AsyncTextureUnsafe <Color32>(RenderConfig.FlatlandsElevationNoiseSource); var unsafeHillsNoise = new AsyncTextureUnsafe <Color32>(RenderConfig.HillsElevationNoiseSource); Vector3 terrainSize = terrainData.size; int mapWidth = terrainData.heightmapWidth; int mapHeight = terrainData.heightmapHeight; float[,] heights = terrainData.GetHeights(0, 0, mapWidth, mapHeight); float maxTextureNormalX = Width / RenderConfig.ChunkWidth; float maxTextureNormalZ = Height / RenderConfig.ChunkHeight; float indexToNormalX = 1f / (mapHeight - 1f); float indexToNormalZ = 1f / (mapWidth - 1f); Vector3 chunkPosition = transform.position; var columnTasks = new Task[mapHeight]; for (int height = 0; height < mapHeight; height++) { int cachedHeight = height; var indexBytes = new byte[2]; PointOrientationData pointOrientation = new PointOrientationData(); var columnTask = new Task(() => { for (int width = 0; width < mapWidth; width++) { float terrainNormalX, terrainNormalZ, textureNormalX, textureNormalZ, worldX, worldZ; Color32 orientationColor; Color weightsColor, duckColor; //For some reason, terrainData seems to index its points //as (y, x) rather than the more traditional (x, y), so //we need to sample our texture accordingly terrainNormalX = cachedHeight * indexToNormalX; terrainNormalZ = width * indexToNormalZ; worldX = chunkPosition.x + terrainNormalX * terrainSize.x; worldZ = chunkPosition.z + terrainNormalZ * terrainSize.z; textureNormalX = maxTextureNormalX * terrainNormalX; textureNormalZ = maxTextureNormalZ * terrainNormalZ; orientationColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeOrientationTexture)); weightsColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeWeightsTexture)); duckColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeDuckTexture)); PointOrientationLogic.GetOrientationDataFromColors( pointOrientation, indexBytes, orientationColor, weightsColor, duckColor ); heights[width, cachedHeight] = HeightLogic.GetHeightForPoint( new Vector2(worldX, worldZ), pointOrientation, unsafeFlatlandsNoise, unsafeHillsNoise ); } }); columnTask.Start(); columnTasks[cachedHeight] = columnTask; } while (columnTasks.Any(task => !task.IsCompleted)) { yield return(SkipFrame); } terrainData.SetHeights(0, 0, heights); }
private IEnumerator RefreshAlphamap(ChunkOrientationData orientationData) { var terrainData = Terrain.terrainData; var unsafeOrientationTexture = new AsyncTextureUnsafe <Color32>(orientationData.OrientationTexture); var unsafeWeightsTexture = new AsyncTextureUnsafe <Color32>(orientationData.WeightsTexture); var unsafeDuckTexture = new AsyncTextureUnsafe <Color32>(orientationData.DuckTexture); Vector3 terrainSize = terrainData.size; int mapWidth = terrainData.alphamapWidth; int mapHeight = terrainData.alphamapHeight; int alphamapLength = RenderConfig.MapTextures.Count(); float[,,] alphaMaps = terrainData.GetAlphamaps(0, 0, mapWidth, mapHeight); float maxTextureNormalX = Width / RenderConfig.ChunkWidth; float maxTextureNormalZ = Height / RenderConfig.ChunkHeight; float indexToNormalX = 1f / (mapHeight - 1f); float indexToNormalZ = 1f / (mapWidth - 1f); Vector3 chunkPosition = transform.position; var columnTasks = new Task[mapHeight]; for (int height = 0; height < mapHeight; height++) { int cachedHeight = height; var indexBytes = new byte[2]; PointOrientationData pointOrientation = new PointOrientationData(); float[] returnMap = new float[RenderConfig.MapTextures.Count()]; float[] intermediateMap = new float[RenderConfig.MapTextures.Count()]; var columnTask = new Task(() => { for (int width = 0; width < mapWidth; width++) { float terrainNormalX, terrainNormalZ, textureNormalX, textureNormalZ, worldX, worldZ; Color32 orientationColor; Color weightsColor, duckColor; //For some reason, terrainData seems to index its points //as (y, x) rather than the more traditional (x, y), so //we need to sample our texture accordingly terrainNormalX = cachedHeight * indexToNormalX; terrainNormalZ = width * indexToNormalZ; worldX = chunkPosition.x + terrainNormalX * terrainSize.x; worldZ = chunkPosition.z + terrainNormalZ * terrainSize.z; textureNormalX = maxTextureNormalX * terrainNormalX; textureNormalZ = maxTextureNormalZ * terrainNormalZ; orientationColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeOrientationTexture)); weightsColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeWeightsTexture)); duckColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeDuckTexture)); PointOrientationLogic.GetOrientationDataFromColors( pointOrientation, indexBytes, orientationColor, weightsColor, duckColor ); AlphamapLogic.GetAlphamapFromOrientation(returnMap, intermediateMap, pointOrientation); for (int alphaIndex = 0; alphaIndex < alphamapLength; alphaIndex++) { alphaMaps[width, cachedHeight, alphaIndex] = returnMap[alphaIndex]; } } }); columnTask.Start(); columnTasks[cachedHeight] = columnTask; } while (columnTasks.Any(task => !task.IsCompleted)) { yield return(SkipFrame); } terrainData.SetAlphamaps(0, 0, alphaMaps); }