stride3d/stride · error · InvalidOperationException
Can't generate lightprobes if less than 4 of them exists.
Error message
Can't generate lightprobes if less than 4 of them exists.
What it means
LightProbeGenerator.GenerateRuntimeData requires at least 4 light probes because it builds a tetrahedralization (Bowyer-Watson) of probe positions, and a tetrahedron needs 4 non-coplanar points. With fewer probes, no valid tetrahedral mesh can be generated, so it throws InvalidOperationException.
Solutions
- Add at least 4 light probes (ideally more, non-coplanar) to the volume/scene before generating runtime data.
- Guard the generation call: only run probe baking/generation when probe count >= 4.
- If the scene is too small for 4 probes, disable light probes or use ambient light instead of probe-based GI.
- Fix volume/selection logic that filters probes down below the threshold unintentionally.
Example fix
// before
LightProbeGenerator.GenerateRuntimeData(probes); // throws if probes.Count < 4
// after
if (probes.Count >= 4)
LightProbeGenerator.GenerateRuntimeData(probes); Defensive patterns
Strategy: validation
Validate before calling
bool canGenerateProbes(List<LightProbeComponent> probes) => probes != null && probes.Count >= 4;
Try / catch
try { LightProbeGenerator.GenerateRuntimeData(probes); } catch (InvalidOperationException ex) { log.Error($"Probe bake skipped: {ex.Message}"); } Prevention
- Place at least 4 non-coplanar probes before baking
- Check probe count in build/cook scripts
- Fall back to ambient lighting on tiny scenes
- Verify volume queries don't filter probes below the threshold
When it happens
Trigger: Calling GenerateRuntimeData (directly or via light probe processing at scene build/cooking time) with a List<LightProbeComponent> containing 0-3 probes.
Common situations: A scene where only a few light probe entities were placed; probes accidentally deleted or filtered out by a volume query; automated tooling generating probes sparsely on small test scenes.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- A negative number of mip maps is not allowed.
- Base path must be non-empty (use null for passthrough).
- BorderColor must be float4(r, g, b, a)
- Build manifest [ ] doesn't exist
- Cannot add an asset with an empty Id
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/c0ae4af93a367926.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Engine/Rendering/LightProbes/LightProbeGenerator.cs:120
// Copy coefficients
if (lightProbe?.Coefficients != null)
{
var lightProbeCoefStart = lightProbeIndex * LambertHamonicOrder * LambertHamonicOrder;
for (var index = 0; index < LambertHamonicOrder * LambertHamonicOrder; index++)
{
destColors[lightProbeCoefStart + index] = index < lightProbe.Coefficients.Count ? lightProbe.Coefficients[index] : new Color3();
}
}
}
}
}
public static unsafe LightProbeRuntimeData GenerateRuntimeData(List<LightProbeComponent> lightProbes)
{
// TODO: Better check: coplanar, etc... (maybe the check inside BowyerWatsonTetrahedralization might be enough -- tetrahedron won't be in positive order)
if (lightProbes.Count < 4)
throw new InvalidOperationException("Can't generate lightprobes if less than 4 of them exists.");
var lightProbePositions = new List<Vector3>();
var lightProbeCoefficients = new Color3[lightProbes.Count * LambertHamonicOrder * LambertHamonicOrder];
var destColors = lightProbeCoefficients.AsSpan();
#if false
ref var destColorsOrigin = ref destColors.GetPinnableReference();
#endif
for (var lightProbeIndex = 0; lightProbeIndex < lightProbes.Count; lightProbeIndex++)
{
var lightProbe = lightProbes[lightProbeIndex];
// Copy light position
lightProbePositions.Add(lightProbe.Entity.Transform.WorldMatrix.TranslationVector);
// Copy coefficients
if (lightProbe.Coefficients != null)
{View on GitHub (pinned to 96fad776d2)