{"record":{"id":"a7cca6d4d8b11728","repo":"stride3d/stride","slug":"cannot-call-postprocess-on-voxel-texture-with-unknown","errorCode":null,"errorMessage":"Cannot call PostProcess on voxel texture with unknown LightFalloff type.","messagePattern":"Cannot call PostProcess on voxel texture with unknown LightFalloff type\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/VoxelLayoutBase.cs","lineNumber":112,"sourceCode":"                mipmapperHeuristic[i] = heuristic;\n            }\n        }\n        virtual public void PostProcess(RenderDrawContext drawContext, LightFalloffs LightFalloff)\n        {\n            if (mipmapperSharp == null)\n            {\n                PrepareMipmapShaders();\n            }\n            switch (LightFalloff)\n            {\n                case LightFalloffs.Sharp:\n                    storageTex.PostProcess(drawContext, mipmapperSharp); break;\n                case LightFalloffs.PhysicallyBased:\n                    storageTex.PostProcess(drawContext, mipmapperPhysicallyBased); break;\n                case LightFalloffs.Heuristic:\n                    storageTex.PostProcess(drawContext, mipmapperHeuristic); break;\n                default:\n                    throw new InvalidOperationException(\"Cannot call PostProcess on voxel texture with unknown LightFalloff type.\");\n            }\n        }\n\n\n        \n\n        protected ValueParameterKey<float> BrightnessInvKey;\n        protected ObjectParameterKey<Stride.Graphics.Texture> DirectOutput;\n\n        virtual public ShaderSource GetVoxelizationShader(List<VoxelModifierEmissionOpacity> modifiers)\n        {\n            var mixin = new ShaderMixinSource();\n            mixin.Mixins.Add(Writer);\n            StorageMethod.Apply(mixin);\n            foreach (var modifier in modifiers)\n            {\n                if (!modifier.Enabled) continue;\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/VoxelLayoutBase.cs#L94-L130","documentation":"VoxelLayoutBase.PostProcess selects a mipmapper based on the voxel texture's LightFalloff setting and applies a post-process pass. The switch over LightFalloffs has no handler for the texture's current value, so an unknown/unset falloff type reaches the default branch. This is an internal invariant: the falloff should always be one of the three known modes by the time post-processing runs.","triggerScenarios":"Calling storageTex.PostProcess (via VoxelLayoutBase.PostProcess) when the storage texture's LightFalloffs value is not PhysicallyBased or Heuristic (and not the case matched before them) — i.e. an uninitialized, default, or future enum member.","commonSituations":"Constructing a voxel texture without explicitly setting LightFalloff; a Stride version upgrade adding a new LightFalloffs member while the voxelization pipeline wasn't updated; deserializing old scene data with an out-of-range falloff value.","solutions":["Set the voxel texture's LightFalloff property to a valid value (PhysicallyBased or Heuristic) before running voxelization/post-process.","Check which LightFalloffs value is set on the texture and add a mapping case if you introduced a new enum member.","If hitting this after upgrading Stride, update the mipmapper selection switch to cover new LightFalloffs members.","If you cannot identify the cause, report it as an internal invariant violation with the falloff value that reached default."],"exampleFix":"// before\nvar layout = VoxelLayout.Create(); // LightFalloff left unset\nlayout.PostProcess(drawContext);\n\n// after\nlayout.LightFalloff = LightFalloffs.PhysicallyBased;\nlayout.PostProcess(drawContext);","handlingStrategy":"validation","validationCode":"if (!Enum.IsDefined(typeof(LightFalloffs), layout.LightFalloff) || layout.LightFalloff is not (LightFalloffs.PhysicallyBased or LightFalloffs.Heuristic))\n    throw new ArgumentException($\"LightFalloff {layout.LightFalloff} is not supported for post-process.\");","typeGuard":"bool IsValidFalloff(LightFalloffs f) => f is LightFalloffs.PhysicallyBased or LightFalloffs.Heuristic;","tryCatchPattern":"try { layout.PostProcess(drawContext); }\ncatch (InvalidOperationException ex) { logger.LogError(ex, \"Voxel post-process failed: unknown LightFalloff {Falloff}\", layout.LightFalloff); }","preventionTips":["Always set LightFalloff explicitly when creating voxel textures.","Exhaustive switch expressions (no default) on LightFalloffs so new enum members break compilation instead of throwing at runtime.","Validate enum values at texture initialization, not at post-process time."],"tags":["voxels","invalid-enum-value","internal-invariant"],"backgroundTag":"invalid-enum-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}