Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion shaders/CompoundCloudPlane.gdshader
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const float CLOUD_MAX_INTENSITY_SHOWN = 1000.f;

float getIntensity(float value)
{
return min(DENSITY_MULTIPLIER * atan(0.006f * CLOUD_MAX_INTENSITY_SHOWN * value), 1.0f) * BrightnessMultiplier;
float baseIntensity = DENSITY_MULTIPLIER * atan(0.006f * CLOUD_MAX_INTENSITY_SHOWN * value);
return min(baseIntensity * BrightnessMultiplier, 1.0f);
}

void fragment() {
Expand Down
25 changes: 3 additions & 22 deletions shaders/MicrobeBackground.gdshader
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ shader_type spatial;
render_mode unshaded;

// this is 1 by default to keep the dark BGs looking nice
uniform float lightLevel = 1.0f;
uniform vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);

uniform vec2 repeats = vec2(1.0f, 1.0f);
uniform sampler2D layer0 : source_color;
Expand Down Expand Up @@ -32,25 +32,6 @@ const vec2 speed3 = vec2(1050.0f);
varying vec2 UV3;
varying vec2 UV4;

vec3 LightInfluence(float amount)
{
if (amount > 0.5f)
{
// Day
return mix(vec3(0.75f, 0.5f, 0.5f), vec3(1.0f, 1.0f, 1.0f), 2.0f * amount - 1.0f);
}
else if (amount > 0.25f)
{
// Dawn and Dusk
return mix(vec3(0.25f, 0.25f, 0.25f), vec3(0.75f, 0.5f, 0.5f), 4.0f * amount - 1.0f);
}
else
{
// Night
return mix(vec3(0.052f, 0.05f, 0.17f), vec3(0.25f, 0.25f, 0.25f), 4.0f * amount);
}
}

void vertex(){
vec2 offset = (repeats - 1.0f) / 2.0f;

Expand Down Expand Up @@ -95,8 +76,8 @@ void fragment(){
vec3 mixture1 = mix(colour2.rgb, colour3.rgb * colour3.a, 1.0f);
vec3 mixture2 = mix(mixture0.rgb, mixture1.rgb, 0.5f);
vec3 composition = mix(colour0.rgb, mixture2.rgb, 0.5f);

ALBEDO.rgb = composition.rgb * LightInfluence(lightLevel);
ALBEDO.rgb = composition.rgb * lightColor;

ALPHA = 1.0f;
}
6 changes: 6 additions & 0 deletions src/general/base_stage/HexEditorComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,12 @@ protected void UpdateVisualLightLevel(float dayLightFraction, Patch currentPatch
var templateMaxLightLevel =
currentPatch.GetCompoundAmountForDisplay(Compound.Sunlight, CompoundAmountType.Template);

currentPatch.Biome.TryGetCompound(Compound.Oxygen, CompoundAmountType.Current, out var oxygen);
var ironAmount =
currentPatch.GetCompoundAmountInSnapshotForDisplay(currentPatch.CurrentSnapshot, Compound.Iron);

camera!.SetWaterColorFromCompounds(oxygen.Ambient, ironAmount);

// Currently, patches whose templates have zero sunlight can be given non-zero sunlight as an instance. But
// nighttime shaders haven't been created for these patches (specifically the sea floor) so for now we can't
// reduce light level in such patches without things looking bad. So we have to check the template light level
Expand Down
17 changes: 13 additions & 4 deletions src/microbe_stage/BackgroundPlane.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public partial class BackgroundPlane : Node3D
private readonly StringName blurAmountParameter = new("blurAmount");
private readonly StringName textureAlbedoParameter = new("textureAlbedo");
private readonly StringName worldPositionParameter = new("worldPos");
private readonly StringName lightLevelParameter = new("lightLevel");
private readonly StringName distortionStrengthParameter = new("distortionFactor");
private readonly StringName lightColorParameter = new("lightColor");

#pragma warning disable CA2213

Expand Down Expand Up @@ -47,6 +47,8 @@ public partial class BackgroundPlane : Node3D

private Vector2 previousWindowSize = new(1280, 720);

private Color previousColor;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be initialized to the same value as in the shader (1, 1, 1, 1)?


public float PlaneOffset
{
get => backgroundPlane.Position.Z;
Expand Down Expand Up @@ -163,9 +165,16 @@ public void SetVisibility(bool visible)
OnDisplayBackgroundParticlesChanged(Settings.Instance.DisplayBackgroundParticles);
}

public void UpdateLightLevel(float lightLevel)
public void SetCompoundColoring(Color color)
{
currentBackgroundMaterial.SetShaderParameter(lightLevelParameter, lightLevel);
// Don't do the calculation and sending to gpu again if not needed.
if (previousColor == color)
return;

previousColor = color;

currentBackgroundMaterial.SetShaderParameter(lightColorParameter,
new Vector3(color.R, color.G, color.B));
}

protected override void Dispose(bool disposing)
Expand All @@ -174,9 +183,9 @@ protected override void Dispose(bool disposing)
{
textureAlbedoParameter.Dispose();
blurAmountParameter.Dispose();
lightLevelParameter.Dispose();
distortionStrengthParameter.Dispose();
worldPositionParameter.Dispose();
lightColorParameter.Dispose();
}

base.Dispose(disposing);
Expand Down
6 changes: 3 additions & 3 deletions src/microbe_stage/BackgroundPlane.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@
frequency = 0.0035

[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_f6pop"]
seamless = true
noise = SubResource("FastNoiseLite_dor76")
seamless = true

[sub_resource type="FastNoiseLite" id="FastNoiseLite_ve355"]
seed = 2
frequency = 0.0017

[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_tsmw6"]
seamless = true
noise = SubResource("FastNoiseLite_ve355")
seamless = true

[sub_resource type="ShaderMaterial" id="2"]
resource_local_to_scene = true
render_priority = -100
shader = ExtResource("4_5y6kw")
shader_parameter/lightLevel = 1.0
shader_parameter/lightColor = Vector3(1, 1, 1)
shader_parameter/repeats = Vector2(2, 1)
shader_parameter/layer0 = ExtResource("5_waqnb")
shader_parameter/layer1 = ExtResource("6_qx2cp")
Expand Down
58 changes: 50 additions & 8 deletions src/microbe_stage/MicrobeCamera.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,16 @@ public partial class MicrobeCamera : Camera3D, ISaveLoadedTracked, IGameCamera,
[Export]
public float LightLevelInterpolateSpeed = 4;

public Color CompoundColor = new(1, 1, 1, 1);
public Color SkyColor = new(1, 1, 1, 1);

#pragma warning disable CA2213
[Export]
private BackgroundPlane backgroundPlane = null!;
#pragma warning restore CA2213

/// <summary>
/// Used to manually tween the light level to the target value
/// </summary>
private float lastSetLightLevel = 1;
[Export]
private MicrobeWorldEnvironment microbeWorldEnvironment = null!;
#pragma warning restore CA2213

private Vector3 cursorWorldPos = new(0, 0, 0);
private bool cursorDirty = true;
Expand All @@ -87,6 +88,8 @@ public partial class MicrobeCamera : Camera3D, ISaveLoadedTracked, IGameCamera,

private float lightLevel = 1.0f;

private float lastSetLightLevel = 0.9f;

[Signal]
public delegate void OnZoomChangedEventHandler(float zoom);

Expand Down Expand Up @@ -179,8 +182,6 @@ public override void _Process(double delta)
{
base._Process(delta);

// Once target is reached the value is set exactly the same
// ReSharper disable once CompareOfFloatsByEqualityOperator
if (lastSetLightLevel != lightLevel)
{
UpdateLightLevel((float)delta);
Expand Down Expand Up @@ -299,6 +300,35 @@ public void SetBackground(Background background)
backgroundPlane.SetBackground(background);
}

public void SetWaterColorFromCompounds(float oxygen, float iron)
{
// A lot of magic numbers here, just parameters to tune this.
// When settled on good values I'll formalise it.
var ironNormalized = iron / 10.0f;
var oxygenNormalize = MathF.Min(oxygen / 0.4f, 1.0f);
float greenIron = ironNormalized * (1.0f - 0.8f * oxygenNormalize);
float redRust = 0.9f * ironNormalized * oxygenNormalize;

var baseGreen = 0.15f;
var baseRed = 0.2f;
var baseBlue = 0.4f;

var g = Math.Clamp(baseGreen + 0.6f * greenIron, 0.0f, 1.0f);
var r = Math.Clamp(baseRed + 0.85f * redRust, 0.0f, 1.0f);
var b = Math.Clamp(baseBlue - 0.25f * ironNormalized, 0.0f, 1.0f);

CompoundColor = new Color(r, g, b);

backgroundPlane.SetCompoundColoring(CompoundColor);
}

public void SetSkyColor(Color envColor)
{
var tintStrength = 0.35f;
var envColorTinted = envColor * (1.0f - tintStrength) + CompoundColor * tintStrength;
SkyColor = DesaturateColor(envColorTinted, 0.15f);
}

public void WritePropertiesToArchive(ISArchiveWriter writer)
{
writer.Write(ZoomSpeed);
Expand Down Expand Up @@ -338,6 +368,14 @@ public void ReadPropertiesFromArchive(ISArchiveReader reader, ushort version)
IsLoadedFromSave = true;
}

private Color DesaturateColor(Color c, float amount)
{
float grayValue = 0.2126f * c.R + 0.7152f * c.G + 0.0722f * c.B;
var gray = new Color(grayValue, grayValue, grayValue);

return c.Lerp(gray, amount);
}

private void UpdateCursorWorldPos()
{
var worldPlane = new Plane(new Vector3(0, 1, 0), 0.0f);
Expand Down Expand Up @@ -427,6 +465,10 @@ private void UpdateLightLevel(float delta)
lastSetLightLevel = lightLevel;
}

backgroundPlane.UpdateLightLevel(lastSetLightLevel);
var waterColor = CompoundColor * (1.0f - lastSetLightLevel) + SkyColor * lastSetLightLevel;
waterColor.A = 1.0f;

backgroundPlane.SetCompoundColoring(waterColor);
microbeWorldEnvironment.UpdateAmbientReflection(SkyColor * lastSetLightLevel);
}
}
36 changes: 28 additions & 8 deletions src/microbe_stage/MicrobeStage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ public sealed partial class MicrobeStage : CreatureStageBase<Entity, MicrobeWorl

[Export]
private GuidanceLine guidanceLine = null!;

[Export]
private MicrobeWorldEnvironment microbeWorldEnvironment = null!;
#pragma warning restore CA2213

private Vector3? guidancePosition;
Expand Down Expand Up @@ -90,6 +87,8 @@ public sealed partial class MicrobeStage : CreatureStageBase<Entity, MicrobeWorl

private float templateMaxLightLevel;

private float previousLightLevel;

private bool appliedPlayerGodMode;

private bool appliedUnlimitGrowthSpeed;
Expand Down Expand Up @@ -1460,6 +1459,10 @@ protected override void UpdatePatchSettings(bool promptPatchNameChange = true)

HUD.UpdateEnvironmentalBars(currentPatch.Biome);

UpdateEnvironmentalCompoundAwareness();

CalculateEnvironmentalLight();

UpdateBackground();

UpdatePatchLightLevelSettings();
Expand Down Expand Up @@ -1500,20 +1503,21 @@ protected override void OnLightLevelUpdate()
var lightLevel =
currentPatch.Biome.GetCompound(Compound.Sunlight, CompoundAmountType.Current).Ambient;

// Don't update the entire lighting pipeline if no need
if (lightLevel == previousLightLevel)
return;

previousLightLevel = lightLevel;

float lightModifier = lightLevel / maxLightLevel;

// Normalise by maximum light level in the patch
Camera.LightLevel = lightModifier;

microbeWorldEnvironment.UpdateAmbientReflection(
currentPatch.BiomeTemplate.EnvironmentColour * lightModifier);
}
else
{
// Don't change lighting for patches without day/night effects
Camera.LightLevel = 1.0f;

microbeWorldEnvironment.UpdateAmbientReflection(currentPatch.BiomeTemplate.EnvironmentColour);
}
}

Expand Down Expand Up @@ -1574,6 +1578,22 @@ private void UpdatePatchLightLevelSettings()
.GetCompound(Compound.Sunlight, CompoundAmountType.Biome).Ambient;
}

private void UpdateEnvironmentalCompoundAwareness()
{
GameWorld.Map.CurrentPatch!.Biome.TryGetCompound(Compound.Oxygen, CompoundAmountType.Current, out var oxygen);
var ironAmount = GameWorld.Map.CurrentPatch.GetCompoundAmountInSnapshotForDisplay(
GameWorld.Map.CurrentPatch.CurrentSnapshot, Compound.Iron);

Camera.SetWaterColorFromCompounds(oxygen.Ambient, ironAmount);
}

private void CalculateEnvironmentalLight()
{
var envColor = GameWorld.Map.CurrentPatch!.BiomeTemplate.EnvironmentColour;

Camera.SetSkyColor(envColor);
}

private void OnFinishLoading()
{
// TODO: re-read the player entity from the simulation as it is not currently saved (there should be a TODO
Expand Down
28 changes: 25 additions & 3 deletions src/microbe_stage/MicrobeStage.tscn
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[gd_scene load_steps=16 format=3 uid="uid://dva08tpqyn15k"]
[gd_scene load_steps=21 format=3 uid="uid://dva08tpqyn15k"]

[ext_resource type="Script" uid="uid://di2y5gnlbsclr" path="res://src/microbe_stage/MicrobeStage.cs" id="1"]
[ext_resource type="PackedScene" uid="uid://bako5jivv1dji" path="res://src/microbe_stage/MicrobeCamera.tscn" id="2"]
[ext_resource type="PackedScene" uid="uid://bt2fv82h01ice" path="res://src/microbe_stage/MicrobeHUD.tscn" id="3"]
[ext_resource type="PackedScene" uid="uid://dew8qwd0buvnb" path="res://src/thriveopedia/fossilisation/FossilisationDialog.tscn" id="4"]
[ext_resource type="Shader" uid="uid://b12xtoy67lhb" path="res://shaders/HeatGradient.gdshader" id="4_a2paa"]
[ext_resource type="PackedScene" uid="uid://dqpjtfkjeuwmq" path="res://src/microbe_stage/MicrobeWorldEnvironment.tscn" id="5_jtm5v"]
[ext_resource type="Texture2D" uid="uid://5y2h7opa1yq6" path="res://src/microbe_stage/HeatGradientNoise.tres" id="5_xncm1"]
[ext_resource type="PackedScene" uid="uid://d3hkouff6asri" path="res://src/microbe_stage/FluidCurrentDisplay.tscn" id="6_4kiki"]
[ext_resource type="Script" uid="uid://cksngbvpy82k0" path="res://src/microbe_stage/PlayerMicrobeInput.cs" id="7"]
[ext_resource type="PackedScene" uid="uid://d1mwl825xlq0t" path="res://src/microbe_stage/HeatGradientPlane.tscn" id="8_7ghg3"]
Expand All @@ -16,25 +18,45 @@
[ext_resource type="PackedScene" uid="uid://b5yuo8sj21lnf" path="res://src/engine/GuidanceLine.tscn" id="75"]
[ext_resource type="PackedScene" uid="uid://dwkek50fju0fu" path="res://src/microbe_stage/PatchNameOverlay.tscn" id="85"]

[node name="MicrobeStage" type="Node" node_paths=PackedStringArray("heatViewOverlay", "fluidCurrentDisplay", "movementModeSelectionPopup", "guidanceLine", "microbeWorldEnvironment", "hudRoot")]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_q12wg"]
frequency = 0.2401

[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_d28l8"]
noise = SubResource("FastNoiseLite_q12wg")

[sub_resource type="ShaderMaterial" id="ShaderMaterial_3c4mw"]
resource_local_to_scene = true
render_priority = -2
shader = ExtResource("4_a2paa")
shader_parameter/heat = ExtResource("5_xncm1")
shader_parameter/noise = SubResource("NoiseTexture2D_d28l8")
shader_parameter/warmColour = Color(1, 0.359565, 0.239655, 1)
shader_parameter/coldColour = Color(0.233659, 0.0244511, 0.882812, 1)
shader_parameter/uvOffset = Vector2(0, 0)
shader_parameter/heatThreshold = 0.5
shader_parameter/alphaMultiplier = 0.077
shader_parameter/noiseMultiplier = 0.099

[node name="MicrobeStage" type="Node" node_paths=PackedStringArray("heatViewOverlay", "fluidCurrentDisplay", "movementModeSelectionPopup", "guidanceLine", "hudRoot")]
process_priority = -1
script = ExtResource("1")
heatViewOverlay = NodePath("World/PrimaryCamera/HeatGradientPlane")
fluidCurrentDisplay = NodePath("World/PrimaryCamera/FluidCurrentDisplay")
movementModeSelectionPopup = NodePath("MovementModeSelectionPopup")
guidanceLine = NodePath("World/GuidanceLine")
microbeWorldEnvironment = NodePath("World/MicrobeWorldEnvironment")
hudRoot = NodePath("MicrobeHUD")

[node name="World" type="Node" parent="."]

[node name="PrimaryCamera" parent="World" instance=ExtResource("2")]
process_mode = 3
AutoProcessWhilePaused = true
microbeWorldEnvironment = NodePath("../MicrobeWorldEnvironment")

[node name="HeatGradientPlane" parent="World/PrimaryCamera" instance=ExtResource("8_7ghg3")]
transform = Transform3D(1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, 1.62921e-06, -10)
visible = false
material_override = SubResource("ShaderMaterial_3c4mw")

[node name="FluidCurrentDisplay" parent="World/PrimaryCamera" instance=ExtResource("6_4kiki")]

Expand Down
Loading