Add heat distortion shader for hot gases (#39107)

This commit is contained in:
Quantum-cross
2025-09-03 23:17:39 -04:00
committed by GitHub
parent 3d89584860
commit 70ffc1eb5d
7 changed files with 444 additions and 15 deletions

View File

@@ -1,6 +1,4 @@
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Content.Server.Atmos.Components;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Components;
@@ -13,7 +11,6 @@ using JetBrains.Annotations;
using Microsoft.Extensions.ObjectPool;
using Robust.Server.Player;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
@@ -32,7 +29,6 @@ namespace Content.Server.Atmos.EntitySystems
[Robust.Shared.IoC.Dependency] private readonly IGameTiming _gameTiming = default!;
[Robust.Shared.IoC.Dependency] private readonly IPlayerManager _playerManager = default!;
[Robust.Shared.IoC.Dependency] private readonly IMapManager _mapManager = default!;
[Robust.Shared.IoC.Dependency] private readonly IConfigurationManager _confMan = default!;
[Robust.Shared.IoC.Dependency] private readonly IParallelManager _parMan = default!;
[Robust.Shared.IoC.Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Robust.Shared.IoC.Dependency] private readonly ChunkingSystem _chunkingSys = default!;
@@ -64,6 +60,12 @@ namespace Content.Server.Atmos.EntitySystems
private EntityQuery<MapGridComponent> _gridQuery;
private EntityQuery<GasTileOverlayComponent> _query;
/// <summary>
/// How much the distortion strength should change for the temperature of a tile to be dirtied.
/// The strength goes from 0.0f to 1.0f, so 0.05f gives it essentially 20 "steps"
/// </summary>
private float _heatDistortionStrengthChangeTolerance;
public override void Initialize()
{
base.Initialize();
@@ -85,9 +87,10 @@ namespace Content.Server.Atmos.EntitySystems
};
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
Subs.CVar(_confMan, CCVars.NetGasOverlayTickRate, UpdateTickRate, true);
Subs.CVar(_confMan, CCVars.GasOverlayThresholds, UpdateThresholds, true);
Subs.CVar(_confMan, CVars.NetPVS, OnPvsToggle, true);
Subs.CVar(ConfMan, CCVars.NetGasOverlayTickRate, UpdateTickRate, true);
Subs.CVar(ConfMan, CCVars.GasOverlayThresholds, UpdateThresholds, true);
Subs.CVar(ConfMan, CVars.NetPVS, OnPvsToggle, true);
Subs.CVar(ConfMan, CCVars.GasOverlayHeatThreshold, UpdateHeatThresholds, true);
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
SubscribeLocalEvent<GasTileOverlayComponent, ComponentStartup>(OnStartup);
@@ -137,6 +140,7 @@ namespace Content.Server.Atmos.EntitySystems
private void UpdateTickRate(float value) => _updateInterval = value > 0.0f ? 1 / value : float.MaxValue;
private void UpdateThresholds(int value) => _thresholds = value;
private void UpdateHeatThresholds(float v) => _heatDistortionStrengthChangeTolerance = MathHelper.Clamp01(v);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Invalidate(Entity<GasTileOverlayComponent?> grid, Vector2i index)
@@ -175,7 +179,9 @@ namespace Content.Server.Atmos.EntitySystems
public GasOverlayData GetOverlayData(GasMixture? mixture)
{
var data = new GasOverlayData(0, new byte[VisibleGasId.Length]);
var data = new GasOverlayData(0,
new byte[VisibleGasId.Length],
mixture?.Temperature ?? Atmospherics.TCMB);
for (var i = 0; i < VisibleGasId.Length; i++)
{
@@ -215,15 +221,17 @@ namespace Content.Server.Atmos.EntitySystems
}
var changed = false;
var temp = tile.Hotspot.Valid ? tile.Hotspot.Temperature : tile.Air?.Temperature ?? Atmospherics.TCMB;
if (oldData.Equals(default))
{
changed = true;
oldData = new GasOverlayData(tile.Hotspot.State, new byte[VisibleGasId.Length]);
oldData = new GasOverlayData(tile.Hotspot.State, new byte[VisibleGasId.Length], temp);
}
else if (oldData.FireState != tile.Hotspot.State)
else if (oldData.FireState != tile.Hotspot.State ||
CheckTemperatureTolerance(oldData.Temperature, temp, _heatDistortionStrengthChangeTolerance))
{
changed = true;
oldData = new GasOverlayData(tile.Hotspot.State, oldData.Opacity);
oldData = new GasOverlayData(tile.Hotspot.State, oldData.Opacity, temp);
}
if (tile is {Air: not null, NoGridTile: false})
@@ -271,6 +279,20 @@ namespace Content.Server.Atmos.EntitySystems
return true;
}
/// <summary>
/// This function determines whether the change in temperature is significant enough to warrant dirtying the tile data.
/// </summary>
private bool CheckTemperatureTolerance(float tempA, float tempB, float tolerance)
{
var (strengthA, strengthB) = (GetHeatDistortionStrength(tempA), GetHeatDistortionStrength(tempB));
return (strengthA <= 0f && strengthB > 0f) || // change to or from 0
(strengthB <= 0f && strengthA > 0f) ||
(strengthA >= 1f && strengthB < 1f) || // change to or from 1
(strengthB >= 1f && strengthA < 1f) ||
Math.Abs(strengthA - strengthB) > tolerance; // other change within tolerance
}
private void UpdateOverlayData()
{
// TODO parallelize?