Improved Level Generator

New asteroid models
Asteroid belts have a custom width curve = tighter belts
Zone Generator uses color theory now
Zone gravity well is much deeper, filled with ambient glow
Gravity waves flow over time
Fog follows gravity waves
Gas Giant shader fixed, offsets distort albedo properly
Fog sample distances follow exponential curve
Fog noise offsets sampling position instead of subtracting density = more natural looking noise
Fog brightness fades out at max view distance
This commit is contained in:
Reinier Vens 2020-12-01 20:38:28 +00:00
commit 34e20c5488
679 changed files with 42717 additions and 209 deletions

View file

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using static Unity.Mathematics.math;
// Thanks to Ian Taylor at https://www.chilliant.com/rgb2hsv.html
public static class ColorMath
{
public static float3 HueToRgb(in float h)
{
float r = abs(h * 6 - 3) - 1;
float g = 2 - abs(h * 6 - 2);
float b = 2 - abs(h * 6 - 4);
return saturate(float3(r,g,b));
}
public static float3 HsvToRgb(in float3 hsv)
{
float3 rgb = HueToRgb(hsv.x);
return ((rgb - 1) * hsv.y + 1) * hsv.z;
}
public static float3 HslToRgb(in float3 hsl)
{
float3 rgb = HueToRgb(hsl.x);
float c = (1 - abs(2 * hsl.z - 1)) * hsl.y;
return (rgb - 0.5f) * c + hsl.z;
}
const float Epsilon = 1e-10f;
public static float3 RgbToHcv(in float3 rgb)
{
// Based on work by Sam Hocevar and Emil Persson
float4 p = (rgb.y < rgb.z) ? float4(rgb.zy, -1.0f, 2.0f/3.0f) : float4(rgb.zy, 0.0f, -1.0f/3.0f);
float4 q = (rgb.x < p.x) ? float4(p.xyw, rgb.x) : float4(rgb.x, p.yzx);
float c = q.x - min(q.w, q.y);
float h = abs((q.w - q.y) / (6 * c + Epsilon) + q.z);
return float3(h, c, q.x);
}
public static float3 RgbToHsv(in float3 rgb)
{
float3 hcv = RgbToHcv(rgb);
float s = hcv.y / (hcv.z + Epsilon);
return float3(hcv.x, s, hcv.z);
}
public static float3 RgbToHsl(in float3 rgb)
{
float3 hcv = RgbToHcv(rgb);
float l = hcv.z - hcv.y * 0.5f;
float s = hcv.y / (1 - abs(l * 2 - 1) + Epsilon);
return float3(hcv.x, s, l);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e37873d142bdaf429c4be95a1d087f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -9,6 +9,9 @@ using static Unity.Mathematics.math;
[Serializable, MessagePackObject(keyAsPropertyName:true), JsonObject]
public class PlanetSettings
{
public float ZoneDepthExponent;
public float ZoneDepth;
public float ZoneBoundaryFog;
public ExponentialCurve GravityDepth;
public ExponentialCurve GravityRadius;
public ExponentialCurve WaveDepth;
@ -59,9 +62,21 @@ public class ZoneGenerationSettings
public float BeltProbability = .05f;
public float BeltMassCeiling = 500f;
public ExponentialCurve AsteroidBeltWidth;
public ExponentialCurve AsteroidCount;
public ExponentialLerp AsteroidRotationSpeed;
public float ResourceDensityMinimum = .1f;
public float ResourceDensityMaximum = 1.5f;
public float SunColorSaturation = .75f;
public float SunSecondaryColorDistance = .25f;
public float SunLightSaturation = .5f;
public float SunFogTintSaturation = .5f;
public ExponentialLerp GasGiantBandCount;
public float GasGiantBandColorSeparation = .25f;
public float GasGiantBandAltColorChance = .25f;
public ExponentialLerp GasGiantBandSaturation;
public ExponentialLerp GasGiantBandBrightness;
}

View file

@ -10,9 +10,6 @@ using Random = Unity.Mathematics.Random;
public class Zone
{
public float ZoneDepth;
public float ZoneDepthExponent;
public float ZoneDepthRadius;
//public HashSet<Guid> Planets = new HashSet<Guid>();
public Dictionary<Guid, Entity> Entities = new Dictionary<Guid, Entity>();
//public Dictionary<Guid, OrbitData> Orbits = new Dictionary<Guid, OrbitData>();
@ -266,7 +263,7 @@ public class Zone
}
public float GetHeight(float2 position)
{
float result = -PowerPulse(length(position)/ZoneDepthRadius, ZoneDepthExponent) * ZoneDepth;
float result = -PowerPulse(length(position)/(Data.Radius*2), _settings.ZoneDepthExponent) * _settings.ZoneDepth;
foreach (var body in PlanetInstances.Values)
{
var p = (position - GetOrbitPosition(body.BodyData.Orbit));

View file

@ -142,7 +142,7 @@ public class ZoneGenerator
Enumerable.Range(0, (int) (settings.AsteroidCount.Evaluate(beltData.Mass.Value * orbitMap[planet].Distance.Value)))
.Select(_ => new Asteroid
{
Distance = random.NextFloat(orbitMap[planet].Distance.Value * .5f, orbitMap[planet].Distance.Value * 1.5f),
Distance = random.NextFloat(orbitMap[planet].Distance.Value, orbitMap[planet].Distance.Value + settings.AsteroidBeltWidth.Evaluate(orbitMap[planet].Distance.Value)),
Phase = random.NextFloat(),
Size = random.NextFloat(),
RotationSpeed = settings.AsteroidRotationSpeed.Evaluate(random.NextFloat())
@ -152,18 +152,46 @@ public class ZoneGenerator
}
else if (planetData is GasGiantData gas)
{
var times = Enumerable.Range(0, 5).Select(i => (float) i / 4).ToArray();
gas.Colors.Value = times.Select(time => float4(random.NextFloat3(),time)).ToArray();
gas.AlbedoRotationSpeed.Value = -3;
gas.FirstOffsetRotationSpeed.Value = 5;
gas.FirstOffsetDomainRotationSpeed.Value = 0;
gas.SecondOffsetRotationSpeed.Value = 10;
gas.SecondOffsetDomainRotationSpeed.Value = -25;
if (planetData is SunData sun)
if (gas is SunData sun)
{
sun.FogTintColor.Value = sun.LightColor.Value = random.NextFloat3();
float primary = random.NextFloat();
float secondary = frac(primary + 1 + settings.SunSecondaryColorDistance * (random.NextFloat() > .5 ? 1 : -1));
gas.Colors.Value = new []
{
float4(ColorMath.HsvToRgb(float3(primary, settings.SunColorSaturation, .5f)), 0),
float4(ColorMath.HsvToRgb(float3(secondary, settings.SunColorSaturation, 1)), 1)
};
sun.FogTintColor.Value = ColorMath.HsvToRgb(float3(primary, settings.SunFogTintSaturation, 1));
sun.LightColor.Value = ColorMath.HsvToRgb(float3(primary, settings.SunLightSaturation, 1));
gas.FirstOffsetDomainRotationSpeed.Value = 5;
}
else
{
// Define primary color and two adjacent colors
float primary = random.NextFloat();
float right = frac(primary + settings.GasGiantBandColorSeparation);
float left = frac(primary + 1 - settings.GasGiantBandColorSeparation);
// Create n time keys from 0 to 1
var bandCount = (int) (settings.GasGiantBandCount.Evaluate(random.NextFloat()) + .5f);
var times = Enumerable.Range(0, bandCount)
.Select(i => (float) i / (bandCount-1));
// Each band has a chance of being either the primary or one of the adjacent hues
// Saturation and Value are random with curves applied
gas.Colors.Value = times
.Select(time => float4(ColorMath.HsvToRgb(float3(
random.NextFloat() > settings.GasGiantBandAltColorChance ? primary : (random.NextFloat() > .5f ? right : left),
settings.GasGiantBandSaturation.Evaluate(random.NextFloat()),
settings.GasGiantBandSaturation.Evaluate(random.NextFloat()))),time))
.ToArray();
gas.FirstOffsetDomainRotationSpeed.Value = 0;
}
gas.AlbedoRotationSpeed.Value = -3;
gas.FirstOffsetRotationSpeed.Value = 5;
gas.SecondOffsetRotationSpeed.Value = 10;
gas.SecondOffsetDomainRotationSpeed.Value = -25;
}
return planetData;
}).ToList();