Skip to content

Game.Rendering.WindControl

Assembly: Assembly-CSharp
Namespace: Game.Rendering

Type: class

Base: System.Object

Summary:
WindControl is a singleton helper that samples wind-related volume parameters (from a WindVolumeComponent) on the CPU, interpolates them over time, and pushes the resulting consolidated wind data to GPU shaders via a constant buffer each frame (registered with the HDRP camera rendering callback). It handles mapping SceneView cameras to the main camera, performs sampling at an interpolation rate defined by the volume, and constructs several float4x4 shader data blocks used by wind shaders (direction, base/gust/tree/flutter parameters, etc.). Designed for use with Unity HDRP and the game's wind volume component.


Fields

  • private struct SampledParameter<T>
    A small helper generic struct that contains a .previous and .current value and helper methods Reset(T) and Update(T) used to store sampled/interpolated parameter states for shader data.

  • private static WindControl s_Instance
    Singleton instance reference. Created on first access to the static instance property.

  • private ShaderVariablesWind m_ShaderVariablesWindCB
    Local instance of the GPU constant-buffer struct used to store wind data before pushing it to GPU. (Type is a shader-generated or engine struct representing the "ShaderVariablesWind" constant buffer layout.)

  • private static readonly int m_ShaderVariablesWind = Shader.PropertyToID("ShaderVariablesWind")
    Cached shader property ID for the global wind constant buffer name "ShaderVariablesWind".

  • private SampledParameter<float> _WindBaseStrengthPhase
    Sampled parameter storing previous/current base strength phase (for wind base sway).

  • private SampledParameter<float> _WindBaseStrengthPhase2
    Sampled parameter storing a second base strength phase.

  • private SampledParameter<float> _WindTreeBaseStrengthPhase
    Sampled parameter storing previous/current tree base strength phase.

  • private SampledParameter<float> _WindTreeBaseStrengthPhase2
    Second phase parameter for tree base strength.

  • private SampledParameter<float> _WindBaseStrengthVariancePeriod
    Sampled parameter storing variance period for base strength.

  • private SampledParameter<float> _WindTreeBaseStrengthVariancePeriod
    Sampled parameter storing variance period for tree base strength.

  • private SampledParameter<float> _WindGustStrengthPhase
    Sampled parameter storing gust strength phase.

  • private SampledParameter<float> _WindGustStrengthPhase2
    Second gust strength phase.

  • private SampledParameter<float> _WindTreeGustStrengthPhase
    Sampled parameter storing tree gust strength phase.

  • private SampledParameter<float> _WindTreeGustStrengthPhase2
    Second tree gust strength phase.

  • private SampledParameter<float> _WindGustStrengthVariancePeriod
    Sampled parameter storing gust strength variance period.

  • private SampledParameter<float> _WindTreeGustStrengthVariancePeriod
    Sampled parameter storing tree gust strength variance period.

  • private SampledParameter<float> _WindFlutterGustVariancePeriod
    Sampled parameter for flutter gust variance period (non-tree).

  • private SampledParameter<float> _WindTreeFlutterGustVariancePeriod
    Sampled parameter for tree flutter gust variance period.

  • private float _LastParametersSamplingTime
    Timestamp (Time.time) of the last parameters sampling; used to throttle interpolation updates according to the volume's interpolation duration.

  • private static readonly float3 kForward = new float3(0f, 0f, 1f)
    Local constant representing a forward unit vector used to compute wind direction vectors.

Properties

  • public static WindControl instance { get; }
    Singleton accessor. If the singleton has not been created it will construct a new WindControl (which registers the beginCameraRendering callback). Use this property to ensure the WindControl is active. The property is read-only (static).

Constructors

  • private WindControl()
    Creates a WindControl instance and subscribes SetupGPUData to RenderPipelineManager.beginCameraRendering. The constructor is private to enforce the singleton pattern.

Methods

  • public void Dispose()
    Unsubscribes the SetupGPUData delegate from RenderPipelineManager.beginCameraRendering and clears the singleton instance (s_Instance = null). Call when the mod or system unloading should stop updating/pushing wind data.

  • private bool GetWindComponent(Camera camera, out WindVolumeComponent component)
    Resolves the active WindVolumeComponent for the provided camera. If the provided camera is a SceneView camera, it remaps to Camera.main before querying. Uses HDCamera.GetOrCreate(camera) and the HDCamera volume stack to obtain the WindVolumeComponent. Returns true if a component was obtained; false otherwise.

  • private void SetupGPUData(ScriptableRenderContext context, Camera camera)
    HDRP per-camera callback registered with beginCameraRendering. If a WindVolumeComponent is found for the camera, this method:

  • obtains a temporary CommandBuffer,
  • calls UpdateCPUData(component) to sample/interpolate parameters on CPU,
  • calls SetGlobalProperties(commandBuffer, component) to write and push constant-buffer data to the GPU,
  • executes and submits the command buffer and releases it. This ensures the global wind data is up-to-date before rendering.

  • private void UpdateCPUData(WindVolumeComponent wind)
    Checks whether enough time (wind.windParameterInterpolationDuration.value) has elapsed since _LastParametersSamplingTime. If so, updates the SampledParameter fields' previous/current values by calling Update(...) with current volume parameter values. This implements discrete sampling for interpolation across frames.

  • private void SetGlobalProperties(CommandBuffer cmd, WindVolumeComponent wind)
    Builds the wind data matrices and vectors used by shaders. Key operations:

  • computes a time value (Time.time in play mode, realtimeSinceStartup otherwise),
  • computes wind direction with variance (using math.radians and cos/period),
  • computes direction vectors (rotated kForward),
  • evaluates animation curves (windGustStrengthControl, windTreeGustStrengthControl) at the chosen time,
  • fills several float4 and float4x4 fields in m_ShaderVariablesWindCB (_WindData_0.._WindData_3) with the sampled previous/current values and material parameters (base/gust/tree/flutter),
  • sets an interpolation factor in one of the entries based on (Time.time - _LastParametersSamplingTime) / interpolationDuration,
  • pushes the constant buffer globally using ConstantBuffer.PushGlobal(cmd, in m_ShaderVariablesWindCB, m_ShaderVariablesWind). The method is wrapped in a ProfilingScope for the "WindGlobalProperties" sampler.

  • private void SampledParameter<T>.Reset(T value)
    Sets both previous and current to the provided value. Useful when initializing sampling state.

  • private void SampledParameter<T>.Update(T value)
    Moves current into previous and sets current to the provided value, so caller can interpolate between previous and current on the GPU.

Usage Example

// Ensure the WindControl singleton is active (registers render callback)
var wc = Game.Rendering.WindControl.instance;

// When unloading / disabling your mod, dispose to unregister the callback:
wc.Dispose();

Notes and remarks: - This class is tied to Unity HDRP (HDCamera, ProfilingSampler IDs, ConstantBuffer.PushGlobal), and expects a WindVolumeComponent type in the volume stack. It will not function correctly outside HDRP or without the matching volume component. - The actual GPU structure layout is represented by ShaderVariablesWind; changes to that layout require corresponding shader updates. - The singleton registers to RenderPipelineManager.beginCameraRendering; keep lifecycle management in mind to avoid duplicate subscriptions on domain reloads or mod reloads.