{"record":{"id":"68a49418b49a505a","repo":"stride3d/stride","slug":"lightbufferdownsamplelevel","errorCode":null,"errorMessage":"LightBufferDownsampleLevel","messagePattern":"LightBufferDownsampleLevel","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShafts.cs","lineNumber":137,"sourceCode":"\n        protected override void Destroy()\n        {\n            base.Destroy();\n            minmaxVolumeEffectShader.Dispose();\n        }\n\n        public void Collect(RenderContext context)\n        {\n            lightShafts = context.VisibilityGroup.Tags.Get(CurrentLightShafts);\n        }\n\n        protected override void DrawCore(RenderDrawContext context)\n        {\n            if (lightShafts == null)\n                return; // Not collected\n\n            if (LightBufferDownsampleLevel < 1)\n                throw new ArgumentOutOfRangeException(nameof(LightBufferDownsampleLevel));\n            if (BoundingVolumeBufferDownsampleLevel < 1)\n                throw new ArgumentOutOfRangeException(nameof(BoundingVolumeBufferDownsampleLevel));\n\n            var depthInput = GetSafeInput(0);\n\n            // Create a min/max buffer generated from scene bounding volumes\n            var targetBoundingBoxBufferSize = new Size2(Math.Max(1, depthInput.Width / BoundingVolumeBufferDownsampleLevel), Math.Max(1, depthInput.Height / BoundingVolumeBufferDownsampleLevel));\n            var boundingBoxBuffer = NewScopedRenderTarget2D(targetBoundingBoxBufferSize.Width, targetBoundingBoxBufferSize.Height, PixelFormat.R32G32_Float);\n\n            // Buffer that holds the minimum distance in case of being inside the bounding box\n            var backSideRaycastBuffer = NewScopedRenderTarget2D(1, 1, PixelFormat.R32G32_Float);\n\n            // Create a single channel light buffer\n            PixelFormat lightBufferPixelFormat = needsColorLightBuffer ? PixelFormat.R16G16B16A16_Float : PixelFormat.R16_Float;\n            var targetLightBufferSize = new Size2(Math.Max(1, depthInput.Width / LightBufferDownsampleLevel), Math.Max(1, depthInput.Height / LightBufferDownsampleLevel));\n            var lightBuffer = NewScopedRenderTarget2D(targetLightBufferSize.Width, targetLightBufferSize.Height, lightBufferPixelFormat);\n            lightShaftsEffectShader.SetOutput(lightBuffer);\n            var lightShaftsParameters = lightShaftsEffectShader.Parameters;","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShafts.cs#L119-L155","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nlightShafts.LightBufferDownsampleLevel = 0; // throws on draw\n// after\nlightShafts.LightBufferDownsampleLevel = Math.Max(1, configuredLevel);","handlingStrategy":"validation","validationCode":"if (lightShafts.LightBufferDownsampleLevel < 1) lightShafts.LightBufferDownsampleLevel = 1;\nif (lightShafts.BoundingVolumeBufferDownsampleLevel < 1) lightShafts.BoundingVolumeBufferDownsampleLevel = 1;","typeGuard":"static bool IsValidDownsampleLevel(int v) => v >= 1;","tryCatchPattern":"try { DrawLightShafts(context); }\ncatch (ArgumentOutOfRangeException) { lightShafts.LightBufferDownsampleLevel = 1; }","preventionTips":["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."],"tags":["argument-out-of-range","downsample","light-shafts","stride"],"backgroundTag":"value-out-of-range","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}