stride3d/stride · error · InvalidOperationException
Cannot call PostProcess on voxel texture with unknown…
Error message
Cannot call PostProcess on voxel texture with unknown LightFalloff type.
What it means
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.
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.
Example fix
// before var layout = VoxelLayout.Create(); // LightFalloff left unset layout.PostProcess(drawContext); // after layout.LightFalloff = LightFalloffs.PhysicallyBased; layout.PostProcess(drawContext);
Defensive patterns
Strategy: validation
Validate before calling
if (!Enum.IsDefined(typeof(LightFalloffs), layout.LightFalloff) || layout.LightFalloff is not (LightFalloffs.PhysicallyBased or LightFalloffs.Heuristic))
throw new ArgumentException($"LightFalloff {layout.LightFalloff} is not supported for post-process."); Type guard
bool IsValidFalloff(LightFalloffs f) => f is LightFalloffs.PhysicallyBased or LightFalloffs.Heuristic;
Try / catch
try { layout.PostProcess(drawContext); }
catch (InvalidOperationException ex) { logger.LogError(ex, "Voxel post-process failed: unknown LightFalloff {Falloff}", layout.LightFalloff); } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- [ . ] must be in
- [ . ] must be in
- height type is not supported.
- EffectCompiler returned no shader and no compilation error.
- PerView VoxelizerStorer layout differs between different…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/a7cca6d4d8b11728.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/VoxelLayoutBase.cs:112
mipmapperHeuristic[i] = heuristic;
}
}
virtual public void PostProcess(RenderDrawContext drawContext, LightFalloffs LightFalloff)
{
if (mipmapperSharp == null)
{
PrepareMipmapShaders();
}
switch (LightFalloff)
{
case LightFalloffs.Sharp:
storageTex.PostProcess(drawContext, mipmapperSharp); break;
case LightFalloffs.PhysicallyBased:
storageTex.PostProcess(drawContext, mipmapperPhysicallyBased); break;
case LightFalloffs.Heuristic:
storageTex.PostProcess(drawContext, mipmapperHeuristic); break;
default:
throw new InvalidOperationException("Cannot call PostProcess on voxel texture with unknown LightFalloff type.");
}
}
protected ValueParameterKey<float> BrightnessInvKey;
protected ObjectParameterKey<Stride.Graphics.Texture> DirectOutput;
virtual public ShaderSource GetVoxelizationShader(List<VoxelModifierEmissionOpacity> modifiers)
{
var mixin = new ShaderMixinSource();
mixin.Mixins.Add(Writer);
StorageMethod.Apply(mixin);
foreach (var modifier in modifiers)
{
if (!modifier.Enabled) continue;
View on GitHub (pinned to 96fad776d2)