Three.jsを使用すると、次のものがあります。
表示されているオブジェクトとカメラの位置を考えると、最終的なカメラの位置を計算して、画面上のオブジェクトに「最適に適合する」方法を選択しましたか?
一部の画面でカメラの位置が「そのまま」使用されると、オブジェクトはビューポートの端を越えて出血しますが、他のオブジェクトは小さく表示されます。オブジェクトをカメラの錐台に収めることは可能だと思いますが、適切なものを見つけることができませんでした。
私はあなたが透視カメラを使用していると仮定しています。
カメラの位置、視野、またはその両方を設定できます。
次の計算は、立方体であるオブジェクトに対して正確であるため、カメラに面するように配置されたオブジェクトの境界ボックスの観点から考えてください。
カメラが中央にあり、キューブを正面から見る場合、
dist = distance from the camera to the _closest face_ of the cube
そして
height = height of the cube.
カメラの視野を次のように設定した場合
fov = 2 * Math.atan( height / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees
キューブの高さは表示される高さと一致します。
この時点で、カメラを少しバックアップするか、視野を少し増やすことができます。
視野が固定されている場合、上記の方程式を使用して距離を解きます。
編集:キューブwidth
を目に見えるwidthに一致させたい場合、aspect
をキャンバスの縦横比(キャンバスの幅をキャンバスの高さで割った値)とし、カメラの視野を次のように設定します
fov = 2 * Math.atan( ( width / aspect ) / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees
three.js r.69
WestLangleysの答えに基づいて、固定カメラの視野で距離を計算する方法があります:
dist = height / 2 / Math.tan(Math.PI * fov / 360);
カメラをオブジェクトが画面に収まるように配置する距離を計算するには、次の式を(Javascriptで)使用できます。
_// Convert camera fov degrees to radians
var fov = camera.fov * ( Math.PI / 180 );
// Calculate the camera distance
var distance = Math.abs( objectSize / Math.sin( fov / 2 ) );
_
ここで、objectSize
はオブジェクトの高さまたは幅です。立方体/球体オブジェクトの場合、高さまたは幅のいずれかを使用できます。長さまたは幅が大きい非キューブ/非球体オブジェクトの場合は、var objectSize = Math.max( width, height )
を使用して大きな値を取得します。
オブジェクトの位置が_0, 0, 0
_にない場合は、カメラの位置を調整してオフセットを含める必要があることに注意してください。
これはCodePenです これが実際に動作していることを示しています。関連する行:
_var fov = cameraFov * ( Math.PI / 180 );
var objectSize = 0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) );
var cameraPosition = new THREE.Vector3(
0,
sphereMesh.position.y + Math.abs( objectSize / Math.sin( fov / 2 ) ),
0
);
_
ウィンドウハンドルをつかんでサイズを変更すると、球体はまだ画面の高さの100%を占めることがわかります。さらに、オブジェクトは、カメラの位置がオブジェクトのスケールを考慮して表示するために、正弦波の方法(0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) )
)で拡大縮小します。
アスペクト比の使用に関するuser151496の提案から、これは機能しているように見えますが、いくつかの異なるパラメータセットでテストしただけです。
var maxDim = Math.max(w, h);
var aspectRatio = w / h;
var distance = maxDim/ 2 / aspectRatio / Math.tan(Math.PI * fov / 360);
orbitControlsでこれを試してください
let padding = 48;
let w = Math.max(objectLength, objectWidth) + padding;
let h = objectHeight + padding;
let fovX = camera.fov * (aspectX / aspectY);
let fovY = camera.fov;
let distanceX = (w / 2) / Math.tan(Math.PI * fovX / 360) + (w / 2);
let distanceY = (h / 2) / Math.tan(Math.PI * fovY / 360) + (w / 2);
let distance = Math.max(distanceX, distanceY);