body {
	background-color: #000;
	margin: 0px;
	overflow: hidden;
}
import * as THREE from 'https://unpkg.com/three@0.116.1/build/three.module.js'
import {OrbitControls} from 'https://unpkg.com/three@0.116.1/examples/jsm/controls/OrbitControls.js'

const visibleHeightAtZDepth = ( depth, camera ) => {
  // compensate for cameras not positioned at z=0
  const cameraOffset = camera.position.z;
  if ( depth < cameraOffset ) depth -= cameraOffset;
  else depth += cameraOffset;

  // vertical fov in radians
  const vFOV = camera.fov * Math.PI / 180;

  // Math.abs to ensure the result is always positive
  return 2 * Math.tan( vFOV / 2 ) * Math.abs( depth );
 };

const visibleWidthAtZDepth = ( depth, camera ) => {
  const height = visibleHeightAtZDepth( depth, camera );
  return height * camera.aspect;
};

// Simple three.js example

var mesh, renderer, scene, camera, controls;

init();
animate();

function init() {

    // renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    // scene
    scene = new THREE.Scene();

    // camera
    camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.set( 0, 0, 20 );

    // controls
    controls = new OrbitControls( camera, document );

    // ambient
    scene.add( new THREE.AmbientLight( 0x222222 ) );

    // light
    var light = new THREE.DirectionalLight( 0xffffff, 1 );
    light.position.set( 0, 20, 0 );
    scene.add( light );

    // full width red rectangle at z = -100
    //const redGeom = new THREE.BoxBufferGeometry( visibleWidthAtZDepth( -100, camera), 1, 1 );
    const redGeom = new THREE.BoxBufferGeometry( 1, 358, 1 );
    const redMat = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
    const redMesh = new THREE.Mesh( redGeom, redMat );
    //redMesh.position.set( 0, 0, -100 );
    redMesh.position.set( 0, 0, -499.27360820770264 );

    // full width blue rectangle at z = -10
    const blueGeom = new THREE.BoxBufferGeometry( visibleWidthAtZDepth( -10, camera), 1, 1 );
    const blueMat = new THREE.MeshBasicMaterial( { color: 0x0000ff } );
    const blueMesh = new THREE.Mesh( blueGeom, blueMat );
    blueMesh.position.set( 0, 5, -10 );

    scene.add( blueMesh, camera );

    camera.add( redMesh );

    console.log( '---: ', findScreenDepth( camera, renderer ) )
}

function findScreenDepth( camera, renderer ) {
    const { near, far } = camera
    const { height:physicalViewHeight } = renderer.getDrawingBufferSize()
    console.log( window.innerHeight, physicalViewHeight )
    const threshold = 0.00000000000001

    return _findScreenDepth( near, far )

    function _findScreenDepth( near, far ) {

        const midpoint = ( far - near ) / 2 + near
        const midpointHeight = visibleHeightAtZDepth( -midpoint, camera )

        if ( Math.abs( ( physicalViewHeight / midpointHeight ) - 1 ) <= threshold )
            return midpoint

        if ( physicalViewHeight < midpointHeight )
            return _findScreenDepth( near, midpoint )
        else if ( physicalViewHeight > midpointHeight )
            return _findScreenDepth( midpoint, far )
        else if ( midpointHeight == physicalViewHeight ) // almost never happens
            return midpoint
    }
}

function animate() {

    requestAnimationFrame( animate );

    //controls.update();

    renderer.render( scene, camera );

}
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.