NSDT工具推荐Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割

本主题讨论透视相机以及如何为远距离环境设置合适的视锥体。

透视相机是一种投影模式,旨在模仿人类在现实世界中看待事物的方式。 这是渲染 3D 场景最常用的投影模式。 - three.js

如果你看一下 Three.js 文档中的透视相机构造函数,它会是这样的:

new THREE.PerspectiveCamera( fov, aspect, near, far )

其中:

  • fov:相机视野
  • aspect: 相机宽高比;
  • near:相机近平面
  • far:相机远平面。

这些参数共同定义了相机的视锥体 - 3D 场景的区域将被渲染并出现在屏幕上。

例如:

const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );

基本上,你可以将 fov、near、far 设置为你想要的任何范围。 例如,将 fov 调整到 10 或 20 左右,你将很容易看到物体的正面,或者实际上所有内容都放大到屏幕上,而如果将 fov 设置为 100 中的 90 左右,则场景中的所有内容都会移得很远。

那么 nearfar 呢?

当然,你也可以设置近平面和远平面的任意值,但如果近远范围很大,那么近距离时会出现更多的 z-fighting,而如果范围太小,则会破坏场景。

理想情况下,如果你设置 near = 0.01,那么far应该是1000,或者 near = 1,那么你可以进一步设置 far = 10000

但是,如果你确实需要像长距离这样的东西,可以使用 near = 0.0000000001far = 10000000000000。但在这种情况下,您可能需要另一个选项来配置 WebGLRenderer。

为什么?

原因是 GPU 的精度有限,无法确定某个物体是在其他物体的前面还是后面。 这种精度分布在近处和远处。 更糟糕的是,默认情况下靠近相机的精度是详细的,而远离相机的精度是粗略的。 这些单位从近开始,随着接近远而慢慢扩展。 - Threejsfundamentals.org

为了说明这种情况,我们有一个带有 3D 模型的简单场景,相机、渲染器的设置如下:

// camera
this.camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight,
  0.00000001,
  10000
);
this.camera.position.set(10, 6, 10);

// renderer
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.physicallyCorrectLights = true;
this.renderer.outputEncoding = THREE.sRGBEncoding;

你认为会发生什么?

3D 模型出了问题,你可以看到纹理全部损坏。 这是 z -fighting的示例,其中计算机上的 GPU 没有足够的精度来确定哪些像素在前面、哪些像素在后面。

有一个解决方案是你需要告诉 Three.js 使用不同的方法来计算哪些像素在前面,哪些像素在后面。 我们可以通过在 WebGLRenderer 构造函数中启用  logarithmicDepthBuffer 来做到这一点。

所以我们的渲染器现在看起来像这样:

// renderer
this.renderer = new THREE.WebGLRenderer({ 
  antialias: true,
  logarithmicDepthBuffer: true
});
// ...

检查结果,它应该可以工作......

logarithmicDepthBuffer 显然可以解决这个问题,但并不总是建议使用它,因为它可能比标准解决方案慢,尤其是在大多数移动设备中。

这意味着你应该始终调整近距和远距以满足你的需要。 现在,请注意,如果想绘制一个距离很远的巨大场景而不破坏场景中的任何对象,你可以尝试一下还有一个替代选项。

希望这可以帮助!


原文链接:Camera near, far and z fighting

BimAnt翻译整理,转载请标明出处