Vixen
02b45cc4
csharp
public sealed class AutoExposureRenderer

The scene reduced to one number, produced on the device and left there for the tonemapper.

Read the guide page for this →

Remarks

K2's last downstream item, and the one that needed every part of it. AutoExposure.rvn has been in the library since the post-process set was written and nothing built the chain, because a chain is what it needs: a compute node, a halving sequence of storage images, and a buffer that survives from one frame to the next. The compute node is K2's; the rest is here.

Why it cannot be a full-screen pass like every other effect in this assembly. Its output is not an image. It reduces the frame to a single value and leaves it in a buffer, and a fragment stage cannot write a buffer at all — it writes the targets bound to it and nothing else. The alternative is a readback, which costs a stall and a frame of latency for a number the host never looks at.

⚠ The exposure buffer is a compositor import, not a declared resource, and that is the whole of what makes adaptation work. A declared buffer lives for one frame; this one holds the value the eye has adapted to, and a buffer that started at zero every frame would make Adapt's ease-toward-target ease from nothing each time — an exposure that never converges and a frame that flickers. So the host owns it, it is registered in BufferImports, and the graph sees it as memory something outside the frame is responsible for.

The chain halves to 1×1 and the last step is the one Adapt reads. Every reduction averages a 2×2 block through a single bilinear tap — a bilinear filter is the average of the four texels it sits between, so the hardware does the reduction for free, which only holds while each step is exactly half the one above it.

⚠ The first step takes the log and the rest do not, which is a permutation rather than a branch: averaging luminance directly lets one specular highlight drag the whole frame's exposure down, and the geometric mean is what "the middle of this scene's brightness" means. Every later step is then a plain average of values that are already logarithmic, and the permutation keeps the colour-space arithmetic out of all of them.

Fields and properties (27)

  • public const int ExposureSize

    How many bytes the exposure buffer holds. One float, and it is the whole point.

  • public const int BinCount

    How many bins the histogram has, which the shader's clear dispatch fixes at 8×8.

  • public const int HistogramSize

    How many bytes the histogram buffer holds.

  • public required string Source

    The linear HDR colour it measures.

  • public SamplerCache? Samplers

    Where the bilinear sampler comes from.

  • public ComputePipelineCache? Pipelines

    Where the compute pipelines come from.

  • public DescriptorAllocator? Allocator

    Where the descriptor sets come from.

  • public IGraphicsDevice? Device

    The device the exposure buffer belongs to.

  • public float DeltaTime

    How long the last frame took, for the adaptation rate.

  • public float BrightenRate

    How fast the eye goes light-adapted, in e-folds per second.

  • public float DarkenRate

    And dark-adapted, which in a real eye is far slower.

  • public float MiddleGrey

    The luminance a correctly exposed mid-grey sits at.

  • public float MinimumExposure

    The lowest exposure the adaptation may settle on.

  • public float MaximumExposure

    And the highest, so a nearly black frame cannot drive it to infinity.

  • public bool UseHistogram

    Whether the frame is metered by a histogram rather than by a geometric mean.

  • public float MinimumLogLuminance

    The darkest luminance the histogram resolves, as a base-2 log.

  • public float MaximumLogLuminance

    And the brightest.

  • public float LowPercentile

    The fraction of the frame discarded from the dark end before the mean is taken.

  • public float HighPercentile

    And from the bright end.

  • public float MeteringPower

    How strongly the centre of the frame counts for more than its edge.

  • public int StartSize

    What the chain's first reduction starts at, in texels.

  • public BufferHandle Exposure

    The buffer the tonemapper reads. Invalid until the first Build.

  • public BufferHandle Histogram

    The bins, for a test or an inspector. Invalid until the first histogram build.

  • public string ExposureResource

    What the exposure buffer is called in the graph.

  • public string HistogramResource

    And the histogram.

  • public int PassCount

    How many dispatches the last build produced — the reductions plus the adaptation.

  • public IReadOnlyList<ComputeRenderer> Steps

    The chain's nodes, the first PassCount of which are this frame's.

Methods (2)

  • 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 (4)

  • AutoExposureTestsVixen.Rendering.PostFx.Tests
  • HarnessVixen.Rendering.PostFx.Tests
  • PostEffectFactoryVixen.Rendering.PostFx
  • PostEffectTestsVixen.Rendering.PostFx.Tests