Skip to content

client(camera): smooth fixed-camera world-space follow and eliminate jitter#10

Open
RZDESIGN wants to merge 4 commits intohytopiagg:mainfrom
RZDESIGN:fixed-camera-smoothing
Open

client(camera): smooth fixed-camera world-space follow and eliminate jitter#10
RZDESIGN wants to merge 4 commits intohytopiagg:mainfrom
RZDESIGN:fixed-camera-smoothing

Conversation

@RZDESIGN
Copy link
Copy Markdown

@RZDESIGN RZDESIGN commented Mar 3, 2026

Summary

Improves fixed-camera feel by smoothing world-space camera attachment/target updates on the client and removing micro-jitter sources in camera orientation/projection updates.

Problem

With fixed cameras driven via setAttachedToPosition(...) + setTargetPosition(...), camera packets can arrive in visible steps.
Result: player appears stable, but the world/map can “shake” or “swim”.

Changes

  • Added smoothing for camera attachedToPosition updates.
  • Added smoothing for camera trackedPosition updates.
  • Switched smoothing to frame-rate independent alpha (exp smoothing).
  • Added deadzone snap for tiny residual deltas (prevents endless micro-movement).
  • Kept/used teleport snap thresholds for large jumps.
  • Guarded against near-zero look-at vectors before computing orientation.
  • Avoided redundant orientation emits when yaw/pitch are effectively unchanged.
  • Updated projection matrix only when lens params actually changed (filmOffset, fov, zoom).
  • Removed a few per-frame allocations in hot camera paths.

Result

  • Smoother and snappier fixed-camera gameplay.
  • Reduced world jitter/shake artifacts.
  • No protocol/API behavior changes required by game code.

RicardoDeZoete added 4 commits March 3, 2026 13:36
- Introduced new collision detection logic in the Camera class to improve camera behavior during gameplay.
- Added methods for sampling game camera collision distance and determining when to sample based on movement and direction.
- Updated EntityManager to include vertical velocity estimation and refined movement direction tracking for better local prediction accuracy.
- Adjusted local prediction parameters for horizontal and vertical movement to enhance responsiveness and stability.
- Added new properties to LocalPredictionState for pre-acknowledgment reconciliation and acknowledgment support detection.
- Updated initialization and reset logic to incorporate new state properties.
- Improved command buffering behavior based on acknowledgment support and pre-acknowledgment grace period.
- Refined reconciliation logic to handle pending commands and ensure smoother movement transitions.
- Introduced new properties for managing attached and tracked camera positions, including targets for smoother transitions.
- Implemented logic to snap positions on large jumps and lerp for gradual adjustments.
- Updated deserialization handling to ensure mutual exclusivity between tracked entity and position.
- Improved camera shoulder rotation handling with a dedicated axis vector.
@web3dev1337
Copy link
Copy Markdown

web3dev1337 commented Mar 4, 2026

Review (camera smoothing)

Nice improvement for fixed-camera world-space follow. Smoothing the packet-driven attached/tracked positions and adding snap-on-teleport should eliminate the small jitter you can get when those positions arrive quantized / irregularly.

What looks good

  • attachedToPosition + trackedPosition now have targets + client-side lerp with a deadzone; this should noticeably reduce camera micro-jitter without needing higher net update rates.
  • Snap thresholds for big deltas avoid “smoothing through walls” after teleports.
  • updateProjectionMatrix() only when filmOffset/fov/zoom actually change.
  • Reuse of temp vectors (shoulderRotationAxis, spectatorForward/right) avoids per-frame/per-packet allocations.

Things to double-check (possible behavior changes)

  • _updateGameCameraOrientation() now normalizes yaw to [-π, π] and suppresses tiny changes via CAMERA_ORIENTATION_EPSILON. If any server/game logic assumes yaw is unwrapped/monotonic, you could see wrap-around jumps near ±π unless the receiver also normalizes/handles angle wrapping.
  • The new smoothing introduces a small lag (~60–80ms time constants) for attachedToPosition / trackedPosition. That’s probably desired for “fixed camera follow”, but if any games use these fields for cutscenes where the camera must match an exact authored path per tick, you may want an opt-out (or make lerp/snap tunables).
  • Hard-coded thresholds (*_SNAP_DISTANCE_*, deadzone) assume “human scale” meters; if some games use very small/large world scales, these may need tuning.

Perf / mobile vs desktop

  • Should be a net win: fewer projection updates + fewer allocations. The extra exp() per frame is negligible.
  • Smoothing is frameDeltaS-based so it should behave consistently across variable FPS (mobile included).

@RZDESIGN
Copy link
Copy Markdown
Author

RZDESIGN commented Mar 5, 2026

Thanks for the review — agreed on splitting and validating behavior details.

I split this into smaller reviewable units while preserving current functionality:

On the review points:

  • Yaw normalization / wrap risk: acknowledged. Current server-side camera usage is trig-based (sin/cos on yaw), so normalized [-pi, pi] should remain behaviorally safe, but I’ll keep this explicitly called out in follow-up validation.
  • Smoothing lag tradeoff: intentional for packet-step jitter reduction; agreed this may need an opt-out/tunable path for authored cutscenes.
  • Scale-sensitive thresholds: agreed. I’ll follow with configurable snap/deadzone knobs so games with non-human scales can tune appropriately.

Appreciate the detailed notes — they helped tighten the split and rollout plan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants