Functions to calculate the visible width / height at a given z-depth from a perspective camera

Aha! After taking a look at this again, I realized that instead of using these functions and a binary search, matching the Three.js perspective to CSS3d perspective boils down to a short equation:

const perspective = 800

// this equation
const fov = 180 * ( 2 * Math.atan( innerHeight / 2 / perspective ) ) / Math.PI

// then align the Three.js perspective with the CSS3D perspective:
camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 0, perspective );
document.body.style.perspective = `${perspective}px`

Here’s a simple example. Note that the blue/pink color is due to the teal WebGL plane rendering on top of the pink DOM plane (zoom the camera to displace the WebGL rendered behind the DOM element):

At this point, the WebGL object and the DOM element can be moved in unison in the same 3D space. For example, let’s animate the positions and rotation of both (again if you zoom, you can see which one is the WebGL and which one is the DOM):

As an follow-on feature would also control the DOM position with the OrbitControls.

2 Likes