Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/scene/camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ class Camera {
this._farClip = newValue;
this._projMatDirty = true;
}
if (this._xr?.active) {
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When XR is active, this setter can change the effective far clip (via _xrProperties.farClip) even if _farClip already equals newValue (e.g., if _xrProperties.farClip was initialized from the XR view projection). In that case _projMatDirty is not set, so projectionMatrix (which uses the getters) can remain stale. Consider marking _projMatDirty = true whenever _xrProperties.farClip changes while XR is active (or broaden the equality check to include _xrProperties.farClip).

Suggested change
if (this._xr?.active) {
if (this._xr?.active) {
// when XR is active, the effective far clip comes from _xrProperties.farClip,
// so mark the projection matrix dirty if that value changes
if (this._xrProperties.farClip !== newValue) {
this._projMatDirty = true;
}

Copilot uses AI. Check for mistakes.
this._xrProperties.farClip = newValue;
this._xr._setClipPlanes(this._xrProperties.nearClip, newValue);
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_setClipPlanes is documented/implemented as a private XrManager method. Calling it directly from Camera tightly couples these modules and makes future refactors harder. Consider adding a public XR API for updating clip planes (or routing this through an event / dedicated method) instead of calling a private underscore method.

Suggested change
this._xr._setClipPlanes(this._xrProperties.nearClip, newValue);
const xr = this._xr;
if (typeof xr.setClipPlanes === 'function') {
xr.setClipPlanes(this._xrProperties.nearClip, newValue);
} else if (typeof xr._setClipPlanes === 'function') {
xr._setClipPlanes(this._xrProperties.nearClip, newValue);
}

Copilot uses AI. Check for mistakes.
}
}

get farClip() {
Expand Down Expand Up @@ -330,6 +334,10 @@ class Camera {
this._nearClip = newValue;
this._projMatDirty = true;
}
if (this._xr?.active) {
this._xrProperties.nearClip = newValue;
Comment on lines 334 to +338
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When XR is active, this setter can change the effective near clip (via _xrProperties.nearClip) even if _nearClip already equals newValue (e.g., _xrProperties.nearClip derived from the XR view). In that case _projMatDirty is not set, so projectionMatrix can remain stale even though the getters now return different values. Consider setting _projMatDirty = true whenever _xrProperties.nearClip changes while XR is active (or include _xrProperties.nearClip in the equality check).

Copilot uses AI. Check for mistakes.
this._xr._setClipPlanes(newValue, this._xrProperties.farClip);
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern here as in farClip: calling the private XrManager method _setClipPlanes from Camera creates cross-module coupling. Prefer a public method on XrManager (or an event-based handoff) for updating the XR session depth near/far.

Suggested change
this._xr._setClipPlanes(newValue, this._xrProperties.farClip);
const xrManager = this._xr;
if (typeof xrManager.setClipPlanes === 'function') {
xrManager.setClipPlanes(newValue, this._xrProperties.farClip);
} else if (typeof xrManager._setClipPlanes === 'function') {
xrManager._setClipPlanes(newValue, this._xrProperties.farClip);
}

Copilot uses AI. Check for mistakes.
}
}

get nearClip() {
Expand Down Expand Up @@ -764,10 +772,10 @@ class Camera {
* @ignore
*/
fillShaderParams(output) {
const f = this._farClip;
const f = this.farClip;
output[0] = 1 / f;
output[1] = f;
output[2] = this._nearClip;
output[2] = this.nearClip;
output[3] = this._projection === PROJECTION_ORTHOGRAPHIC ? 1 : 0;
return output;
}
Expand Down