bevyengine/bevy · error · AutoExposureCompensationCurveError
discontinuity found between curve segments
Error message
discontinuity found between curve segments
What it means
After building the cubic curve, `from_curve` walks every segment and requires each one to start exactly where the previous sample ended (`segment.position(0.0) == previous`). A gap or jump in the log-luminance (x) domain between segments returns `AutoExposureCompensationCurveError::DiscontinuityFound` (crates/bevy_post_process/src/auto_exposure/compensation_curve.rs:120), because the LUT bake assumes a continuous curve.
Source
Thrown at crates/bevy_post_process/src/auto_exposure/compensation_curve.rs:49
/// The lookup table for the curve. Uploaded to the GPU as a 1D texture.
/// Each value in the LUT is a `u8` representing a normalized exposure compensation value:
/// * `0` maps to `min_compensation`
/// * `255` maps to `max_compensation`
///
/// The position in the LUT corresponds to the normalized log luminance value.
/// * `0` maps to `min_log_lum`
/// * `LUT_SIZE - 1` maps to `max_log_lum`
lut: [u8; LUT_SIZE],
}
/// Various errors that can occur when constructing an [`AutoExposureCompensationCurve`].
#[derive(Error, Debug)]
pub enum AutoExposureCompensationCurveError {
/// The curve couldn't be built in the first place.
#[error("curve could not be constructed from the given data")]
InvalidCurve,
/// A discontinuity was found in the curve.
#[error("discontinuity found between curve segments")]
DiscontinuityFound,
/// The curve is not monotonically increasing on the x-axis.
#[error("curve is not monotonically increasing on the x-axis")]
NotMonotonic,
}
impl Default for AutoExposureCompensationCurve {
fn default() -> Self {
Self {
min_log_lum: 0.0,
max_log_lum: 0.0,
min_compensation: 0.0,
max_compensation: 0.0,
lut: [0; LUT_SIZE],
}
}
}
View on GitHub (pinned to 396ca72708)
Solutions
- Check that x values are contiguous across the whole input — no skipped log-luminance values between segments
- Rebuild the curve from a single sorted, gap-free point list
- Validate the junction points programmatically before calling `from_curve`
Example fix
// before: gap between segments -> DiscontinuityFound let pts = [vec2(-4.0, -2.0), vec2(-1.0, -1.0), vec2(2.0, 1.0)]; // jump 2.0 -> skipped range // after: dense, contiguous sampling of the intended function let pts = (-40..=40).map(|i| vec2(i as f32 / 10.0, (i as f32 / 40.0).powi(3))).collect::<Vec<_>>(); let curve = AutoExposureCompensationCurve::from_points(pts)?;
Defensive patterns
Strategy: try-catch
Validate before calling
let mut pts: Vec<Vec2> = points.to_vec();
pts.sort_by(|a, b| a.x.partial_cmp(&b.x).unwrap());
// contiguity sanity check before handing to the converter
for w in pts.windows(2) {
assert!(w[1].x > w[0].x, "duplicate/decreasing x values");
} Try / catch
match AutoExposureCompensationCurve::from_points(pts) {
Err(AutoExposureCompensationCurveError::DiscontinuityFound) => {
warn!("gaps in compensation curve; falling back to linear interpolation of endpoints");
fallback_curve(pts)
}
other => other?,
} Prevention
- Author curves as dense samples of a function rather than hand-placed sparse points
- Validate junction continuity (segment end == next segment start) in asset tooling
When it happens
Trigger: Feeding `from_points`/`from_curve` data whose consecutive segments don't chain on the x-axis: points with a gap between segment boundaries, or a custom `CubicGenerator` whose segments cover disjoint intervals.
Common situations: Hand-authored compensation curves from spreadsheets/JSON where an x value was skipped or mistyped; splicing two curves together without blending the junction.
Related errors
- curve could not be constructed from the given data
- curve is not monotonically increasing on the x-axis
- Unable to generate cubic curve: at least one set of control
- Not enough data to build curve: needed at least {expected} c
- Could not construct an EvenCore
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/da9fae9b77d858d3.
Report an issue: GitHub.