0

I have a three.js scene that is using ArrayCamera with 2 cameras. One is first-person, the other an aerial view. For the aerial view, I'm rendering 2 spheres but only one is visible. It seems anything with a position.z value greater than 0 doesn't render but I'm not sure why.

Codepen

import * as THREE from "https://esm.sh/three";

// https://threejs.org/examples/#webgl_camera_array

const canvasWidth = window.innerWidth;
const canvasHeight = window.innerHeight;
const canvasPixelRatio = Math.min(window.devicePixelRatio, 2);

// Divide by 2 because each camera takes up half the viewport.
const cameraWidth = (window.innerWidth / 2) * window.devicePixelRatio;
const cameraHeight = window.innerHeight * window.devicePixelRatio;
const cameraAspectRatio = cameraWidth / cameraHeight;

const layout = document.querySelector("#myDiv");

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

// MESHES
const sphere1 = new THREE.Mesh(
  new THREE.SphereGeometry(0.5),
  new THREE.MeshBasicMaterial({ color: "white", wireframe: true })
);
sphere1.position.set(0, 0, -1);
scene.add(sphere1);
const sphere2 = new THREE.Mesh(
  new THREE.SphereGeometry(0.5),
  new THREE.MeshBasicMaterial({ color: "white", wireframe: true })
);
sphere2.position.set(0, 0, 1);
scene.add(sphere2);

// Ground plane
const meshPlane = new THREE.Mesh(
  new THREE.PlaneGeometry(100, 100, 40, 40),
  new THREE.MeshBasicMaterial({
    color: "white",
    wireframe: true
  })
);
meshPlane.rotation.x = Math.PI / 2; // Rotate to lie flat
scene.add(meshPlane);

// First-person camera
const firstPersonCamera = new THREE.PerspectiveCamera(
  75,
  cameraAspectRatio,
  0.1,
  100
);
firstPersonCamera.position.set(0, 0, 5); // In front of cube
firstPersonCamera.lookAt(0, 0, -1); // Look forward
// Not sure what this is doing but without it, things break.
firstPersonCamera.updateMatrixWorld();

const aerialCamera = new THREE.OrthographicCamera(
  cameraWidth / -2,
  cameraWidth / 2,
  cameraHeight / 2,
  cameraHeight / -2,
  0,
  2000
);
aerialCamera.position.set(0, 1, 0); // Above origin
aerialCamera.lookAt(0, 0, 0); // Look down
aerialCamera.zoom = 40;
// Not sure what this is doing but without it, things break.
aerialCamera.updateMatrixWorld();

const cameras = new THREE.ArrayCamera([firstPersonCamera, aerialCamera]);
cameras.cameras[0].viewport = new THREE.Vector4(
  0,
  0,
  cameraWidth,
  cameraHeight
); // Left half
cameras.cameras[1].viewport = new THREE.Vector4(
  cameraWidth,
  0,
  cameraWidth,
  cameraHeight
); // Right half
// Must be called after any change of parameters.
cameras.cameras[0].updateProjectionMatrix();
cameras.cameras[1].updateProjectionMatrix();

const helper = new THREE.CameraHelper(cameras);
scene.add(helper);

// HELPERS
const axesHelper = new THREE.AxesHelper();
scene.add(axesHelper);

// RENDERER
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(canvasWidth, canvasHeight);
renderer.setPixelRatio(canvasPixelRatio);
layout.appendChild(renderer.domElement);

// ANIMATE
function onNewFrame() {
  renderer.render(scene, cameras);
}
renderer.setAnimationLoop(onNewFrame);

1 Answer 1

0
sphere1.position.set(0, 0, -1);
sphere2.position.set(0, 0, 1);

Those sphere's both need an negative Z. But that will overlap them, so lets move one to the left, and one to the right. Also place them more behind so they are still inside your frustum:

sphere1.position.set(-1, 0, -5);
sphere2.position.set(1, 0, -5);

Gives: enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Not sure why they would be required for the aerial camera. From what I can tell, its frustum is covering a large part of the positive z area.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.