You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js ArrayCamera无法渲染特定位置对象的问题求助

问题分析与解决方案

核心问题原因

俯视正交相机无法显示position.z>0的物体,主要由两个问题导致:

  1. 正交相机near值设置为0:Three.js要求相机近裁剪面必须大于0,设为0会引发深度缓冲计算异常,导致本该显示的物体被错误裁剪。
  2. 视锥体参数与场景空间不匹配:原代码用像素值定义正交相机的left/right/top/bottom,虽通过zoom调整,但容易出现视锥体范围与世界空间物体比例失调的问题。

修复步骤

1. 修正近裁剪面参数

将OrthographicCamera的near参数从0改为大于0的数值(如0.1),避免深度计算错误。

2. 改用世界空间单位定义视锥体

放弃像素值,改用世界空间单位定义正交相机的视锥体范围,让参数逻辑更贴合3D场景,再通过zoom调整显示比例。

3. 移除冗余矩阵更新

lookAt()方法会自动更新相机视图矩阵,无需手动调用updateMatrixWorld(),可删除这部分冗余代码。

修复后的代码示例

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

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

const cameraAspectRatio = (window.innerWidth / 2) / window.innerHeight;

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

// 场景
const scene = new THREE.Scene();

// 球体网格
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);

// 地面平面
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;
scene.add(meshPlane);

// 第一人称相机
const firstPersonCamera = new THREE.PerspectiveCamera(
  75,
  cameraAspectRatio,
  0.1,
  100
);
firstPersonCamera.position.set(0, 0, 5);
firstPersonCamera.lookAt(0, 0, -1);

// 修复后的俯视正交相机
const aerialViewSize = 10; // 世界空间中的视图高度
const aerialCamera = new THREE.OrthographicCamera(
  -aerialViewSize * cameraAspectRatio,
  aerialViewSize * cameraAspectRatio,
  aerialViewSize,
  -aerialViewSize,
  0.1, // 近裁剪面设为0.1
  2000
);
aerialCamera.position.set(0, 10, 0); // 提升相机高度,优化俯视视角
aerialCamera.lookAt(0, 0, 0);
aerialCamera.zoom = 0.8; // 调整缩放比例适配场景

// 数组相机配置
const cameras = new THREE.ArrayCamera([firstPersonCamera, aerialCamera]);
const cameraWidth = (window.innerWidth / 2) * canvasPixelRatio;
const cameraHeight = window.innerHeight * canvasPixelRatio;
cameras.cameras[0].viewport = new THREE.Vector4(0, 0, cameraWidth, cameraHeight); // 左半视口
cameras.cameras[1].viewport = new THREE.Vector4(cameraWidth, 0, cameraWidth, cameraHeight); // 右半视口

// 更新投影矩阵
cameras.cameras[0].updateProjectionMatrix();
cameras.cameras[1].updateProjectionMatrix();

// 辅助元素
const helper = new THREE.CameraHelper(cameras);
scene.add(helper);
const axesHelper = new THREE.AxesHelper();
scene.add(axesHelper);

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

// 动画循环
function onNewFrame() {
  renderer.render(scene, cameras);
}
renderer.setAnimationLoop(onNewFrame);

额外说明

  • 提升俯视相机高度至(0,10,0),确保两个球体和地面都能完整显示在视口中。
  • 改用世界空间单位定义视锥体,参数更直观,便于后续调整场景元素。

内容的提问来源于stack exchange,提问作者Brad Woods

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:10:53