public override void WriteColorMap(int height, string filePath) { var width = 2 * height; if (ColorNoiseMap == null) { GenerateColorMap(height); } var bitmap = new DirectBitmap(width, height); var tempMean = Random.Uniform("life temperature mean", FreezingPoint, BoilingPoint); var tempVariance = Random.Uniform("life temperature variance", 20, 70); var sinPower = Random.Uniform("sin power", 0, 2); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { var value = ColorNoiseMap.GetValue(x, y); var col = OceanColor; if (!HasOcean || HeightNoiseMap.GetValue(x, y) > OceanLevel) { col = ColorScale.Color(value); } if (HasLife && HeightNoiseMap.GetValue(x, y) > OceanLevel) { var delta = Abs(TemperatureNoiseMap.GetValue(x, y) - tempMean) / tempVariance; if (delta < 0) { delta = 0; } if (delta > 1) { delta = 1; } delta *= (float)Pow(Sin(PI * y / height), sinPower); col = Interpolate(col, LifeColorScale.Color(value), delta); } if (HasAtmosphere && TemperatureNoiseMap.GetValue(x, y) < FreezingPoint * IceFactor) { col = IceColor; } bitmap.SetPixel(x, y, col); } } bitmap.Save(filePath); }
private void GenerateTemperatureMap(int height) { var width = 2 * height; if (HeightNoiseMap == null) { GenerateHeightMap(height); } var builder = new SphereNoiseMapBuilder(); builder.SetDestSize(width, height); builder.SetBounds(-90, 90, -180, 180); TemperatureNoiseMap = new NoiseMap(); builder.SourceModule = TemperatureNoiseModule; builder.DestNoiseMap = TemperatureNoiseMap; builder.Build(); MinTemperature = 1000000.0f; MaxTemperature = 0.0f; var solarHeat = Pow(SurfaceTemperature, 4); var extraHeat = Pow(GeothermalTemperature, 4) + Pow(GreenhouseTemp, 4); var coldness = 1 - (float)Random.Uniform("coldness", Pow(extraHeat / (solarHeat + extraHeat), 0.25), 1); if (HasAtmosphere) { for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { var heat = extraHeat + solarHeat * 2 * Sin(PI * y / height); var temperature = (float)Pow(heat, 0.25); temperature *= 1 - coldness * HeightNoiseMap.GetValue(x, y); if (temperature < MinTemperature) { MinTemperature = temperature; } else if (temperature > MaxTemperature) { MaxTemperature = temperature; } temperature *= 1 + 0.05f * (TemperatureNoiseMap.GetValue(x, y) - 1); TemperatureNoiseMap.SetValue(x, y, temperature); } } } }
/// <summary>Writes an equirectangular height map of the planet at the specified path.</summary> /// <param name="height">The height of the output image, half the width.</param> /// <param name="filePath">The path of the output file including file extension.</param> public void WriteHeightMap(int height, string filePath) { if (HeightNoiseMap == null) { GenerateHeightMap(height); } var bitmap = new DirectBitmap(HeightNoiseMap.Width, HeightNoiseMap.Height); for (var x = 0; x < HeightNoiseMap.Width; x++) { for (var y = 0; y < HeightNoiseMap.Height; y++) { var col = Interpolate(Color.Black, Color.White, HeightNoiseMap.GetValue(x, y)); bitmap.SetPixel(x, y, col); } } bitmap.Save(filePath); }
/// <summary>Writes an equirectangular specular map of the planet at the specified path.</summary> /// <param name="height">The height of the output image, half the width.</param> /// <param name="filePath">The path of the output file including file extension.</param> public void WriteSpecMap(int height, string filePath) { if (HasOcean) { var bitmap = new DirectBitmap(HeightNoiseMap.Width, HeightNoiseMap.Height); if (HasOcean) { for (var x = 0; x < HeightNoiseMap.Width; x++) { for (var y = 0; y < HeightNoiseMap.Height; y++) { var col = Color.Black; if (HeightNoiseMap.GetValue(x, y) <= OceanLevel && TemperatureNoiseMap.GetValue(x, y) > FreezingPoint) { col = Color.White; } bitmap.SetPixel(x, y, col); } } } bitmap.Save(filePath); } }
/// <summary>Writes an equirectangular normal map of the planet at the specified path.</summary> /// <param name="height">The height of the output image, half the width.</param> /// <param name="filePath">The path of the output file including file extension.</param> /// <param name="altMode">Whether to use an alternate normal map format.</param> public void WriteNormalMap(int height, string filePath, bool altMode = false) { var width = 2 * height; if (HeightNoiseMap == null) { GenerateHeightMap(height); } var array = new float[width, height]; var bitmap = new DirectBitmap(width, height); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { var value = HeightNoiseMap.GetValue(x, y); if (value < OceanLevel) { value = 0; } else { value = (value - OceanLevel) / (1 - OceanLevel); } value *= (float)Sin(PI * y / height); array[x, y] = value; } } for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { var r = 127; var g = 127; var b = 255; if (x > 0 && x < width - 1 && y > 0 && y < height - 1) { var vx = new Vector3(100f / height, 0, array[x + 1, y] - array[x - 1, y]); var vy = new Vector3(0, 100f / height, array[x, y + 1] - array[x, y - 1]); var c = Vector3.Cross(vx, vy); c /= c.Length(); r = (int)(255 * (1 + c.X) / 2); g = (int)(255 * (1 - c.Y) / 2); b = (int)(255 * (1 + c.Z) / 2); } if (altMode) { var A = r; var G = (int)(g * A / 255.0); if (A < 0 || A > 255 || G < 0 || G > 255) { bitmap.SetPixel(x, y, Color.FromArgb(127, 255, 127, 255)); } else { bitmap.SetPixel(x, y, Color.FromArgb(A, G, G, G)); } } else { if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { bitmap.SetPixel(x, y, Color.FromArgb(127, 127, 255)); } else { bitmap.SetPixel(x, y, Color.FromArgb(r, g, b)); } } } } bitmap.Save(filePath); }