Vixen
c7401864
csharp
public sealed class WaterRenderer

The water pass: absorption and scattering integrated over the depth of water, composited once.

Read the guide page for this →

Remarks

[35 § D8](../../docs/plan/35-water.md#d8-the-surface-is-a-pass-between-lighting-and-translucency-and-its-reflections-are-l5s), and what overview § 1.9 recorded transmission / refraction as waiting for. It runs after deferred lighting and before ordinary translucency, reads a copy of the scene colour and the depth buffer, and writes back into the scene colour.

⚠ The copy is the point, not fussiness. Sampling a target a pass is also writing is undefined — not slow, not approximate — which is why § B1 called the blocker the copy rather than the pass, and why !Copy exists. Name it in Behind and put a !Copy node ahead of this one.

Integrated, not blended. Alpha blending gives a surface whose opacity is a number somebody typed; absorption over a path length gives one whose colour and opacity are both consequences of how deep it is — a shallow edge clear because the path is short, going green-blue and then black over metres because the long wavelengths go first, from one coefficient triple rather than a gradient somebody painted.

⚠ The reflection plane is doc 19 § L5's, not SSR's, and that is routing rather than compromise. Unreal's water pass classifies tiles specifically so it can run an indirect SSR draw over them, because SSR is what it has. Vixen's SSR is ⬜ and its traced reflections are ✅ — so a lake reflects a mountain that is off screen, which is the single most common reflection failure in every screen-space implementation. Leave Reflections empty and the pass compiles the variant without it.

⚠ Its alpha is the waterline mask, not an opacity. § D9's underwater composite reads it per pixel, because a camera straddling the surface needs two treatments in one frame divided by a curve a post-process volume's single per-frame weight cannot express.

Fields and properties (29)

  • public required string Output

    The target it writes — the frame's scene colour.

  • public required string Behind

    The copy of the frame so far, which is what is behind the water.

  • public required string SceneDepth

    The opaque scene's depth, which says how far away what is behind is.

  • public required string Surface

    The surface plane: device depth in r, coverage in g.

  • public required string Normal

    The surface's world normal in xyz and its foam in a.

  • public string Reflections

    Doc 19 § L5's plane — radiance in rgb, validity in a. Optional.

  • public RenderView? View

    The view the camera matrices are derived from, or null to set them by hand.

  • public Matrix4x4 InverseViewProjection

    Clip back to world, when no View supplies it.

  • public Vector3 CameraPosition

    Where the camera is, which both distances are measured from.

  • public Vector3 Scattering

    How much light the medium scatters out of a ray per metre, per channel.

  • public Vector3 Absorption

    How much it absorbs per metre, per channel.

  • public float PhaseG

    Henyey–Greenstein anisotropy. Water is forward-scattering, around 0.7.

  • public Vector3 BehindScale

    § D8's scale on what is behind the water.

  • public Vector3 SunColour

    The radiance the volume scatters.

  • public Vector3 SunDirection

    Which way the light travels.

  • public Vector3 SkyColour

    What arrives from the whole sky — the term that makes water blue rather than dark.

  • public float SurfaceF0

    Water against air.

  • public Vector3 FoamColour

    What foam is, where the surface plane's alpha says there is some.

  • public bool Foam

    Whether foam is blended over the result at all.

  • public bool Tiled

    Whether the pass runs over the screen tiles that have water in them rather than over the screen — § D8's tile classification.

  • public ComputePipelineCache? Pipelines

    Where the classification's compute pipeline comes from. Null turns tiling off.

  • public Int2 TileCount

    How many tiles covered the target the last time this built, or zero when untiled.

  • public EffectPipelineDescriber? Modules

    Where shader modules come from. Set before the first frame that builds.

  • public SamplerCache? Samplers

    Where samplers come from, shared so a frame does not exhaust the device's supply.

  • public DescriptorAllocator? Allocator

    Where the pass's descriptor sets come from.

  • public IGraphicsDevice? Device

    The device its pipelines and its uniform block are created on.

  • public FullScreenRenderer Pass

    The pass this node is, for a host that wants to look at what it did.

  • public ComputeRenderer Classification

    And the classification dispatch ahead of it, which runs only when Tiled.

  • public int BuildCount

    How many frames have declared the pass.

Methods (3)

  • public WaterRenderer()

    Creates the node.

  • protected override void Build(GraphicsCompositor compositor, CompositorFrame frame)

    Declares this node's render-graph passes.

  • public void Dispose()

    Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

Used by (3)

  • WaterPassImageTestsVixen.Graphics.Golden.Tests
  • WaterPassTestsVixen.Rendering.Water.Tests
  • WaterRendererFactoryVixen.Rendering.Water