admin管理员组

文章数量:1419230

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 ";;

// 

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);

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./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);
Share Improve this question asked Jan 29 at 11:51 Brad WoodsBrad Woods 1,5462 gold badges14 silver badges31 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 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:

本文标签: threejsthreejs array camera not rendering objects at specific positionsStack Overflow