three_js_gpu_picking
three_js_gpu_picking copied to clipboard
Cameras with the projection matrix set directly (VR, AR) don't setup their frustum properly
PerspectiveCamera.setViewOffset()
ignores the projection matrix and uses the fov, near & far values to re-create the projection matrix when you call it. With a camera provided by an AR system like 8thwall, or WebVR/WebXR, these values are not set, so you get a default frustum, which is incorrect.
In our internal code I changed it to use a separate camera & calculate the fov/near/far from the projection of the input camera - not quite correct, as the projection may have a pixel shift as well, but better than before:
const projection = this.camera.projectionMatrix.elements;
const fov = Math.atan(1 / projection[5]) * 2;
const aspect = projection[5] / projection[0];
const A = projection[10];
const B = projection[14];
const near = B / (A - 1);
const far = B / (A + 1);
this.cameraClone.fov = fov * (180 / Math.PI);
this.cameraClone.aspect = aspect;
this.cameraClone.near = near;
this.cameraClone.far = far;
...
this.cameraClone.setViewOffset(w, h, x, y, 1, 1);
I use this cloned camera for rendering, but the existing camera to retrieve the renderLists.