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

  1. Set the voxel texture's LightFalloff property to a valid value (PhysicallyBased or Heuristic) before running voxelization/post-process.
  2. Check which LightFalloffs value is set on the texture and add a mapping case if you introduced a new enum member.
  3. If hitting this after upgrading Stride, update the mipmapper selection switch to cover new LightFalloffs members.
  4. 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

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


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)