繁体   English   中英

Aframe/Three 适合屏幕 - 计算缩放

[英]Aframe/Three fit to screen - calculate zoom

我想将相机放大到三帧/一帧,以便图像适合屏幕。

这是我正在使用的代码:

    this._camera = document.getElementById('camera').getAttribute('camera')
    this._ratio = this._assetWidth/this._assetHeight

    this._vFOV = window.THREE.Math.degToRad( this._camera?.fov || 80 )

    this._height = 2 * Math.tan( this._vFOV / 2 ) * this.data.distance
    this._width = this._height * this._ratio

    this._zoom = this._ratio > 1 ? this._width/window.innerWidth : this._height/window.innerHeight

    console.log(this._zoom,  this._ratio, this._width, window.innerWidth)

我已经到了需要计算缩放的部分,以便 object 适合屏幕,即横向适合宽度,纵向适合高度。

我以为这就是答案,但事实并非如此。 那是计算相机 position 而不是变焦值。

我坚持你如何计算缩放值。

有什么线索吗?

通过以下方式将 object 安装到屏幕上:

  • 更改相机 FoV
  • 缩放相机
  • 重新定位相机 / object

一旦您了解公式的来源,就会非常相似。
我们将使用这张整洁的图片( 来自这个 SO 线程),因为它涵盖了所有三个主题:

在此处输入图像描述

0. 我们想要实现什么

我们希望 object(其宽度或高度的较长边)覆盖filmHeight - 所以它适合屏幕。

1. 重新计算 FoV

在这种情况下,我们确实知道focalLength (相机与对象的距离)和filmHeight (对象宽度或高度)。 感谢我们的朋友trigonometry ,我们可以计算fov / 2

Tan (fov / 2) = (filmHeight / 2) / focalLength
=> fov = 2 * ATan ((filmHeight / 2)) / focalLength * 180 / PI

 <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script> <script> AFRAME.registerComponent("fit", { init: function() { const plane = document.querySelector("a-plane") const distance = this.el.object3D.position.distanceTo(plane.object3D.position) var height = plane.getAttribute("geometry").height var newFov = 2 * Math.atan((height / 2) / distance) * (180 / Math.PI); // in degrees this.el.sceneEl.camera.fov = newFov } }) </script> <a-scene> <a-plane position="0 1.6 -2" material="src: https://i.imgur.com/wjobVTN.jpg"></a-plane> <a-camera position="0 1.6 0" fit></a-camera> </a-scene>

2.重新定位object/摄像头

相同的三角形不同的变量。 现在我们想知道focalLength
Tan (fov / 2) = (filmHeight / 2) / focalLength
=> focalLength = (filmHeight / 2) / Tan (fov / 2)

 <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script> <script> AFRAME.registerComponent("fit", { init: function() { const plane = document.querySelector("a-plane") const height = plane.getAttribute("geometry").height const fov = this.el.sceneEl.camera.fov * (Math.PI / 180); const newDistance = Math.abs((height / 2) / Math.tan(fov / 2)) plane.object3D.position.z = -1 * newDistance; } }) </script> <a-scene> <a-plane position="0 1.6 -2" material="src: https://i.imgur.com/wjobVTN.jpg"></a-plane> <a-camera position="0 1.6 0" fit></a-camera> </a-scene>

3. 缩放相机

如果我们知道相机应该离 object 多远才能填满屏幕 - 我们知道当前距离和新距离之间的关系是什么:

zoom = currentDistance / necessaryDistance

 <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script> <script> AFRAME.registerComponent("fit", { init: function() { const plane = document.querySelector("a-plane"); const distance = this.el.object3D.position.distanceTo(plane.object3D.position); const height = plane.getAttribute("geometry").height; const fov = this.el.sceneEl.camera.fov * (Math.PI / 180); const newDistance = Math.abs((height / 2) / Math.tan(fov / 2)); this.el.sceneEl.camera.zoom = distance / newDistance; } }) </script> <a-scene> <a-plane position="0 1.6 -2" material="src: https://i.imgur.com/wjobVTN.jpg"></a-plane> <a-camera position="0 1.6 0" fit></a-camera> </a-scene>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM