public sealed class ForwardLightingRenderFeatureWhich lights reach each object, and getting that list to the shader.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
Stride's ForwardLightingRenderFeature model, which docs/plan/06 names as the forward path's per-object light list and as the fallback the clustered path degrades to where compute is absent. A fragment iterates the lights its object was given rather than every light in the scene, which is what makes a scene with two hundred lights cost what a scene with eight does.
Lights are selected against objects, never against the view frustum. That looks like a missed optimisation and is a correctness requirement: a lamp behind the camera lights everything in front of it, so culling lights by the frustum would darken exactly the objects that are on screen. The frustum has already done its work — the objects considered here are the ones that survived it.
One buffer, one descriptor, a per-draw offset. Every object's block lives in one uniform buffer and is reached through DynamicUniformBuffer, so a thousand objects cost a thousand offsets rather than a thousand descriptor sets. Allocating a set per draw is the single most common reason a Vulkan renderer ends up slower than the D3D11 one it replaced.
One set per frame, from a DescriptorAllocator, not one set for ever. The buffer is recreated when the scene outgrows it, and a set held across frames would have to be rewritten to point at the new one — which is a write to a set the frames still in flight are reading, and drivers execute that without a word. The ring is exactly FramesInFlight deep, so the set this frame writes is one no frame still in flight can be reading. The buffer needs no such care: IGraphicsDevice defers every destruction until the frames that could reference the handle have retired, which descriptor writes have no equivalent of.
The directional light is not in the list. It has no position to test against an object, so it reaches everything, and paying list traversal for something present in every list is paying for nothing — ForwardPlus.rvn takes it as its own uniform for the same reason. Sun is what a per-frame binder reads.
Fields and properties (33)
public const int HeaderSizeHow many bytes precede the light array in the block.
public const int ProbeIndexOffsetWhere the chosen probe's index sits in the header.
public const int ProbeWeightOffsetWhere the chosen probe's weight sits in the header.
public override string NameThe sub-feature's name, for logging and profiling.
public RenderDataKey<LightAssignment> AssignmentsWhere each object's block starts, and how many lights it holds.
public IList<RenderLight> LightsThe scene's lights. Filled by whatever extracts them.
public int MaxLightsPerObjectHow many lights one object's block has room for.
public int OffsetAlignmentWhat a dynamic uniform offset must be a multiple of.
public IGraphicsDevice? DeviceThe device the light buffer lives on. Set before the first frame that prepares.
public bool ClusteredWhether the scene's lights are culled into a cluster grid instead of into per-object lists.
public BufferHandle SceneBufferEvery light in the scene, as the culling pass reads them.
public int SceneLightCountHow many lights the scene buffer holds this frame.
public int SceneLightBaseWhich entry of SceneBuffer this frame's lights start at.
public ParameterCollection? SceneWhere to publish the scene's light buffer, or null to publish it nowhere.
public string ShaderNameWhich pass's names to publish under.
public IReadOnlyList<PermutationKey<bool>> PermutationKeyspublic bool UseRecordsWhether this frame's per-object scalars go into a buffer rather than into a bound block.
public BufferHandle RecordBufferThe buffer the per-object records live in, for a host binding it once a frame.
public int RecordBaseWhich record this frame's objects start at.
public ReadOnlySpan<ObjectRecord> RecordsWhat was written this frame, for a test or an inspector.
public DescriptorSetSlot SlotWhich descriptor set the block is bound to.
public ReflectionProbeSelector? ProbesWhich reflection probe each object gets, or null to leave every object without one.
public uint BindingWhich binding within that set.
public ShaderStage StagesWhich stages read the light list.
public RenderLight? SunThe brightest directional light, or null when the scene has none.
public BufferHandle BufferThe buffer every object's block lives in.
public DescriptorSetHandle DescriptorsThis frame's set, valid from the moment Prepare has run.
public bool IsRecordingpublic DescriptorSetLayoutHandle LayoutThe layout its set is made from — the pass's own, taken from the effect.
public MaterialRenderFeature? MaterialsWhere an unset Layout is taken from, once a shader has resolved.
public int SetCountHow many sets the ring has had to create, which settles at frames-in-flight.
public int BlockStrideHow many bytes one object's block occupies, alignment included.
public int UsedBytesHow many bytes of the buffer this frame filled.
Methods (9)
public ForwardLightingRenderFeature()Creates the feature, interning its permutation key.
public bool ValueOf(RenderSystem system, RenderObjectId id, int index)This sub-feature's value for one object and one of its keys.
public bool EnableRecords(PermutationKey<bool> shaderKey, bool addressable)Turns the per-object record path on, where the draw can address a record at all.
public ReadOnlySpan<byte> Block(RenderSystem system, RenderObjectId id)The bytes written for one object, for a test or an inspector.
public IEnumerable<PunctualLightData> LightsFor(RenderSystem system, RenderObjectId id)The lights one object was given, brightest first.
protected internal override void Initialize(RenderSystem system)Registers this sub-feature's per-object data. Called once.
protected internal override void Prepare(RenderSystem system)public void Draw(RenderSystem system, RenderDrawContext context, in RenderNode node)Records this sub-feature's contribution for one node.
public void Dispose()Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Used by (23)
- ArenaThirdPersonShooter
- ClusteredLightingTestsVixen.Rendering.Tests
- ClusteredShadingDeviceTestsVixen.Graphics.Golden.Tests
- CompositorBuilderVixen.Rendering
- DrawCompactionTestsVixen.Rendering.Tests
- ForwardFrameTestsVixen.Rendering.Tests
- ForwardLightingTestsVixen.Rendering.Tests
- ForwardPlusLayoutTestsVixen.Rendering.Tests
- FrameVixen.Rendering.Tests
- GpuDrivenCompositorTestsVixen.Rendering.Tests
- HarnessVixen.Rendering.Tests
- HarnessVixen.Rendering.Tests
- HarnessVixen.Rendering.Tests
- HarnessVixen.Rendering.Tests
- HarnessVixen.Rendering.Tests
- IrradianceBounceDeviceTestsVixen.Graphics.Golden.Tests
- IrradianceShadingDeviceTestsVixen.Graphics.Golden.Tests
- LightExtractionSystemVixen.Rendering
- LightExtractionTestsVixen.Rendering.Tests
- MaterialRecordBufferTestsVixen.Rendering.Tests
- ObjectRecordTestsVixen.Rendering.Tests
- SceneLightingTestsVixen.Rendering.Tests
- WorldRendererVixen.Engine.Renderer