thebluefish/bevy_contrib_schedules

Query remainder of frame time to allow for interpolation (for rendering)

Opened this issue · 0 comments

The final part of this article (Gaffer on Games) deals with interpolation to get rid of undesirable stutter. It explains the reasoning for this better than I could.

You could provide some sort of API to query how much time remains in the accumulator for a schedule - or rather, it would probably be more suitable just to provide the fraction (let alpha = accumulator / timestep).

Then, an end-user is responsible for tracking current and previous state and interpolating between them, e.g.:

struct Position(Vec3);
struct PreviousPosition(Vec3);

// after the physics simulation, within the main schedule
fn before_render(
    schedule_runner: Res<ScheduleRunner>, // Fixed Schedule, provided as a resource
    query: Query<(&mut Transform, &Position, &PreviousPosition)>,
) {
    let alpha: f32 = schedule_runner.alpha(); // example API, calculates `accumulator / timestep` (only for schedules with fixed timesteps)
    for (mut transform, new_position, previous_position) in query.iter_mut() {
        // position and previous_position were updated by our physics simulation
        // transform determines where the sprite will actually render
        // below is equivalent to: transform.translation = previous_position.0 * (1.0 - alpha) + new_position.0 * alpha;
        transform.translation = previous_position.0.lerp(new_position.0, alpha);
    }
}