stride3d/stride · error · ArgumentOutOfRangeException
LightBufferDownsampleLevel
Error message
LightBufferDownsampleLevel
What it means
In DrawCore, LightShafts validates that both LightBufferDownsampleLevel and BoundingVolumeBufferDownsampleLevel are at least 1, throwing ArgumentOutOfRangeException with the property name when not. Downsample levels of 0 or below would produce degenerate buffers and divide-by-zero scaling, so the renderer fails fast each draw.
Solutions
- Set LightBufferDownsampleLevel (and BoundingVolumeBufferDownsampleLevel) to a value >= 1; use 1 for full resolution.
- Clamp loaded/configured values: Math.Max(1, level) before assignment.
- Note the thrown argument name in the message to identify exactly which of the two properties is invalid.
Example fix
// before lightShafts.LightBufferDownsampleLevel = 0; // throws on draw // after lightShafts.LightBufferDownsampleLevel = Math.Max(1, configuredLevel);
Defensive patterns
Strategy: validation
Validate before calling
if (lightShafts.LightBufferDownsampleLevel < 1) lightShafts.LightBufferDownsampleLevel = 1; if (lightShafts.BoundingVolumeBufferDownsampleLevel < 1) lightShafts.BoundingVolumeBufferDownsampleLevel = 1;
Type guard
static bool IsValidDownsampleLevel(int v) => v >= 1;
Try / catch
try { DrawLightShafts(context); }
catch (ArgumentOutOfRangeException) { lightShafts.LightBufferDownsampleLevel = 1; } Prevention
- Treat 1 as the minimum downsample level ('full resolution'), not 0.
- Clamp deserialized/serialized values to >= 1 after loading a scene.
- In editor scripts, expose the property with a minimum of 1.
When it happens
Trigger: Setting LightBufferDownsampleLevel to 0 (or negative) on the LightShafts component/renderer — directly in code, in the editor property grid, or via serialization — then rendering a frame where light shafts are collected (lightShafts != null).
Common situations: Assuming 0 means 'no downsampling' (the minimum is 1, meaning full resolution); resetting a component to default int 0 in scripts or factory code before rendering.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Custom strides is not supported with packed PixelFormats
- Destination texture is a MSAA texture.
- Indices for Int2 run from 0 to 1, inclusive.
- Indices for Int3 run from 0 to 2, inclusive.
- Indices for Int4 run from 0 to 3, inclusive.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/68a49418b49a505a.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShafts.cs:137
protected override void Destroy()
{
base.Destroy();
minmaxVolumeEffectShader.Dispose();
}
public void Collect(RenderContext context)
{
lightShafts = context.VisibilityGroup.Tags.Get(CurrentLightShafts);
}
protected override void DrawCore(RenderDrawContext context)
{
if (lightShafts == null)
return; // Not collected
if (LightBufferDownsampleLevel < 1)
throw new ArgumentOutOfRangeException(nameof(LightBufferDownsampleLevel));
if (BoundingVolumeBufferDownsampleLevel < 1)
throw new ArgumentOutOfRangeException(nameof(BoundingVolumeBufferDownsampleLevel));
var depthInput = GetSafeInput(0);
// Create a min/max buffer generated from scene bounding volumes
var targetBoundingBoxBufferSize = new Size2(Math.Max(1, depthInput.Width / BoundingVolumeBufferDownsampleLevel), Math.Max(1, depthInput.Height / BoundingVolumeBufferDownsampleLevel));
var boundingBoxBuffer = NewScopedRenderTarget2D(targetBoundingBoxBufferSize.Width, targetBoundingBoxBufferSize.Height, PixelFormat.R32G32_Float);
// Buffer that holds the minimum distance in case of being inside the bounding box
var backSideRaycastBuffer = NewScopedRenderTarget2D(1, 1, PixelFormat.R32G32_Float);
// Create a single channel light buffer
PixelFormat lightBufferPixelFormat = needsColorLightBuffer ? PixelFormat.R16G16B16A16_Float : PixelFormat.R16_Float;
var targetLightBufferSize = new Size2(Math.Max(1, depthInput.Width / LightBufferDownsampleLevel), Math.Max(1, depthInput.Height / LightBufferDownsampleLevel));
var lightBuffer = NewScopedRenderTarget2D(targetLightBufferSize.Width, targetLightBufferSize.Height, lightBufferPixelFormat);
lightShaftsEffectShader.SetOutput(lightBuffer);
var lightShaftsParameters = lightShaftsEffectShader.Parameters;View on GitHub (pinned to 96fad776d2)