Game.Simulation.SnowSystem
Assembly: Game
Namespace: Game.Simulation
Type: class
Base: GameSystemBase, IDefaultSerializable, ISerializable, IPostDeserialize
Summary:
SnowSystem implements the GPU-driven snow simulation used by the game. It stores snow depth in two 1024×1024 RenderTextures (ping‑pong), updates snow accumulation, melting and transfer using ComputeShaders, maintains a 1×1024 backdrop height texture for distant rendering, and integrates with TerrainSystem, ClimateSystem, WaterSystem, WindSimulationSystem and TimeSystem. It also provides (de)serialization logic to save/load snow data to/from the save file. The class is optimized to run most heavy work on the GPU via command buffers and compute kernels, and exposes controls such as SnowSimSpeed for update frequency.
Fields
-
public struct ushort2
Small nested struct with two ushorts (x, y). Used to represent 16‑bit packed snow data when serializing / deserializing legacy formats. -
private static ILog log
Logger used for warnings/errors during serialization and runtime. -
private const int kTexSize
Constant texture size (1024). Size used for snow textures. -
private const int kGroupSizeAddSnow
Compute group size constant used when dispatching Add kernel (16). -
private const int kNumGroupAddSnow
Number of groups for Add kernel (64). -
private const float kTimeStep
Simulation timestep constant (0.2f) used for snow update kernels. -
private const float kSnowHeightScale
Scale for snow height (8f) used when mapping older formats. -
private const float kSnowMeltScale
Melt scaling constant. -
private const float m_SnowAddConstant
Constant used as the base add multiplier (1E-05f). -
private const float m_WaterAddConstant
Constant used for water influence (0.1f). -
private const int kSnowHeightBackdropTextureSize
Backdrop texture length (1024). -
private const float kSnowBackdropUpdateLerpFactor
Default lerp factor used when updating backdrop (0.1f). -
private RenderTexture m_snowHeightBackdropTextureFinal
The 1×1024 final backdrop texture containing prefiltered snow heights used for distant rendering. -
private ComputeBuffer m_snowBackdropBuffer
GPU compute buffer used during backdrop height computation/finalization. -
private ComputeBuffer m_MinHeights
Compute buffer that stores minimum heights for blocks/tiles used by backdrop generation. -
private RenderTexture[] m_SnowHeights
Ping‑pong array of two 1024×1024 RenderTextures storing snow depth (R16G16_UNorm). -
private CommandBuffer m_CommandBuffer
Single CommandBuffer used to batch compute dispatches and texture updates. -
private ComputeShader m_SnowUpdateShader
Main compute shader used for snow reset/load/add/transfer/backdrop kernels. -
private int m_TransferKernel
Kernel index for "Transfer" compute kernel. -
private int m_AddKernel
Kernel index for "Add" compute kernel (accumulation & melting). -
private int m_ResetKernel
Kernel index for "Reset" kernel. -
private int m_LoadKernel
Kernel index for "Load" kernel (16‑bit format). -
private int m_LoadOldFormatKernel
Kernel index for loading older float4 formats. -
private int m_UpdateBackdropSnowHeightTextureKernel
Kernel index used for computing backdrop min heights. -
private int m_ClearBackdropSnowHeightTextureKernel
Kernel index used to clear the backdrop buffer. -
private int m_FinalizeBackdropSnowHeightTextureKernel
Kernel index used to finalize the backdrop 1×1024 texture. -
private int m_ID_SnowDepth
Shader property ID mapped to result snow depth texture. -
private int m_ID_OldSnowDepth
Shader property ID mapped to previous (read) snow depth texture. -
private int m_ID_Timestep
Shader property ID for timestep. -
private int m_ID_AddMultiplier
Shader property ID for add multiplier. -
private int m_ID_MeltMultiplier
Shader property ID for melt multiplier. -
private int m_ID_AddWaterMultiplier
Shader property ID for added water multiplier. -
private int m_ID_ElapseWaterMultiplier
Shader property ID for water elapse multiplier. -
private int m_ID_Temperature
Shader property ID for temperature. -
private int m_ID_Rain
Shader property ID for precipitation. -
private int m_ID_Wind
Shader property ID for wind vector. -
private int m_ID_Time
Shader property ID for normalized simulation time. -
private int m_ID_SnowScale
Shader property ID for snow scale vector. -
private int m_ID_MinHeights
Shader property ID for the min heights compute buffer. -
private int m_ID_SnowHeightBackdropBuffer
Shader property ID for the backdrop buffer. -
private int m_ID_SnowHeightBackdropFinal
Shader property ID for the final backdrop texture. -
private int m_ID_SnowBackdropUpdateLerpFactor
Shader property ID for the backdrop lerp factor. -
private int m_ID_SnowHeightBackdropBufferSize
Shader property ID for the backdrop buffer size (1024). -
private TerrainSystem m_TerrainSystem
Reference to TerrainSystem (heightmap, height scale). -
private SimulationSystem m_SimulationSystem
Reference to the simulation system. -
private TimeSystem m_TimeSystem
Reference to TimeSystem for normalized time/date. -
private ClimateSystem m_ClimateSystem
Reference to ClimateSystem (temperature, precipitation, base heights). -
private WindSimulationSystem m_WindSimulationSystem
Reference to wind simulation for constant wind vector. -
private WaterSystem m_WaterSystem
Reference to WaterSystem (water texture).
Properties
-
public RenderTexture SnowHeightBackdropTexture => m_snowHeightBackdropTextureFinal
Readonly accessor for the final 1×1024 snow backdrop texture used by shaders for distant snow rendering. -
public int SnowSimSpeed { get; set; }
Controls how many snow update iterations run each OnUpdate call (default set to 1 in OnCreate). Increasing this speeds the simulation at cost of GPU time. -
public int2 TextureSize => new int2(1024, 1024)
Returns the configured snow texture size as int2. -
public bool Loaded => m_SnowUpdateShader != null
Indicates whether the snow update shader has been initialized (i.e., system is ready). -
public ComputeShader m_SnowTransferShader { private get; set; }
Transfer shader slot (private getter). Present for injection/configuration but primary compute work is in m_SnowUpdateShader. -
public ComputeShader m_DynamicHeightShader { private get; set; }
Slot for dynamic height compute shader (private getter). -
private float4 SnowScaleVector => new float4(8f, 1f, 1f, 1f)
Internal scale vector used when loading old formats or setting shader parameters. -
private int Write { get; set; }
Index of the current write buffer (0 or 1) in m_SnowHeights used for ping‑pong. -
private int Read => 1 - Write
Read index computed as the opposite of Write. -
public RenderTexture SnowDepth
Returns the current read snow depth RenderTexture (null if textures not initialized). -
public bool IsAsync { get; set; }
Flag indicating whether certain operations can run asynchronously (not used extensively in this class).
Constructors
public SnowSystem()
Default constructor. Initialization is performed in the preserved override OnCreate where shaders, textures and system references are configured.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns update interval for system scheduling. SnowSystem returns 4 (i.e., runs on a coarser schedule). -
private void InitShader()
Loads the snow update compute shader from AssetDatabase.global.resources.shaders.snowUpdate and caches kernel indices for Reset, Load, LoadOldFormat, Add, Transfer, UpdateBackdropSnowHeightTexture, ClearBackdropSnowHeightTexture and FinalizeBackdropSnowHeightTexture. -
public unsafe void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
Serializes snow data into the save: writes width/height (1024,1024) then reads back the current snow texture (GPU -> NativeArray via AsyncGPUReadback) and compresses/filters it before writing to the writer. Uses 16‑bit ushort2 packing when appropriate. -
public void PostDeserialize(Context context)
Called after deserialization. For older versions (pre-snow version) it resets both snow textures. Also sets the global "_SnowMap" shader texture to the current SnowDepth. -
public void DebugReset()
Utility that resets both ping‑pong snow textures by dispatching the Reset kernel to both write and read textures. -
public unsafe void Deserialize<TReader>(TReader reader) where TReader : IReader
Reads snow data from save. Handles different save versions: - If Version.snow16bits or newer: reads packed ushort2 array, unfilters, uploads to a ComputeBuffer, and dispatches the Load kernel to populate both ping‑pong textures and backdrop buffers.
-
If older: reads float4 arrays (legacy) and dispatches LoadOldFormat kernel with SnowScaleVector. After loading, it sets global scale vector ("colossal_SnowScale") and prepares backdrop texture. The method also logs warnings if saved dimensions don't match expectations.
-
public void SetDefaults(Context context)
Resets snow textures to defaults (dispatches Reset kernel) and sets global "_SnowMap" texture. -
public void UpdateDynamicHeights()
Placeholder method in current implementation (empty). Intended to update dynamic height data when present. -
private RenderTexture CreateTexture(string name)
Helper to create a 1024×1024 RenderTexture configured as R16G16_UNorm, with random write enabled and Clamp wrap; used for snow height textures. -
private void InitTextures()
Initializes m_SnowHeights[2], m_MinHeights buffer, m_snowBackdropBuffer and the final backdrop RenderTexture (1×1024 R32_SFloat). Called during OnCreate. -
[Preserve] protected override void OnCreate()
System setup: calls InitShader, acquires references to required systems (TerrainSystem, SimulationSystem, TimeSystem, ClimateSystem, WaterSystem, WindSimulationSystem), initializes textures and shader property IDs, creates a CommandBuffer and sets default SnowSimSpeed = 1. Also registers required data (RequireForUpdate). -
[Preserve] protected override void OnDestroy()
Disposes the CommandBuffer, destroys RenderTextures and releases compute buffers created during OnCreate/InitTextures. -
private void FlipSnow()
Swaps Write index between 0 and 1 for ping‑ponging. -
private float GetSnowiness()
Small helper that computes a periodic value based on normalized date (not used directly in current code path). -
private void AddSnow(CommandBuffer cmd)
Dispatches the "Add" kernel using the command buffer. Sets multiple compute parameters (timestep, add/melt/water multipliers, temperature, rain, wind, scale, time) and binds Terrain heightmap, previous & current snow textures, water texture and the min heights buffer. Dispatches kernel and flips the ping‑pong buffers. -
private void SnowTransfer(CommandBuffer cmd)
Dispatches the "Transfer" kernel which models snow transport when conditions are right. It early‑outs when precipitation is low or temperature is above threshold. Binds old/current snow textures, terrain heightmap and wind vector and dispatches the kernel, then flips the ping‑pong buffers. -
private void UpdateSnowBackdropTexture(CommandBuffer cmd, float lerpFactor)
Updates the 1×1024 backdrop texture: clears the backdrop buffer, accumulates min heights (using m_MinHeights), finalizes the backdrop texture using the lerpFactor, and writes into m_snowHeightBackdropTextureFinal. -
[Preserve] protected override void OnUpdate()
Runs every scheduled tick (GetUpdateInterval applied). If WaterSystem is loaded, clears CommandBuffer, runs AddSnow and SnowTransfer SnowSimSpeed times, updates the backdrop texture (with lerp 0.1), sets global "_SnowMap" to current SnowDepth, and executes the command buffer.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Initialize compute shader kernels and textures
InitShader();
InitTextures();
// Grab references to required systems
m_TerrainSystem = World.GetOrCreateSystemManaged<TerrainSystem>();
m_TimeSystem = World.GetOrCreateSystemManaged<TimeSystem>();
m_ClimateSystem = World.GetOrCreateSystemManaged<ClimateSystem>();
m_WaterSystem = World.GetOrCreateSystemManaged<WaterSystem>();
m_WindSimulationSystem = World.GetOrCreateSystemManaged<WindSimulationSystem>();
// Prepare command buffer and property IDs
m_CommandBuffer = new CommandBuffer { name = "Snowsystem" };
SnowSimSpeed = 1;
}
If you want, I can also: - generate concise diagrams showing the ping‑pong workflow and compute kernel dispatch order, - extract the shader kernel names and parameters into a single quick reference, - or produce step‑by‑step guidance for modders to change SnowSimSpeed, add custom compute kernels, or hook into serialization.