ウェブサイト検索

javascript - Three.js で平面のサイズを全体表示に設定する


私は日本人で、英語が得意ではありません、すみません。

私は Three.js を勉強しています。

カメラのすぐ前に背景としてプレーンを設定したいです。

そして、Planeの背景がウィンドウ(レンダラー)を完全に満たしたいのです。

でも今はこんな感じです。

その飛行機は青いです。

それは少し小さいです。

こちらがコードです。

function init() {
    var scene = new THREE.Scene();

    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    scene.add(camera);

    camera.position.x = 0;
    camera.position.y = 0;
    camera.position.z = 100;
    camera.lookAt(scene.position); // (0, 0, 0)

    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(new THREE.Color(0xe3e3e3));
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;

    var spotLight = new THREE.SpotLight(0xffffff);
    spotLight.position.set(50, 50, 50);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // I want to put Plane's size as full background. not (82, 82 * window.innerHeight / window.innerWidth)
    var planeGeometry = new THREE.PlaneGeometry(82, 82 * window.innerHeight / window.innerWidth);
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0x123abc});
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;
    plane.position.x = 0;
    plane.position.y = 0;
    plane.position.z = 0;

    scene.add(plane);

    var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
    var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
    var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

    cube.position.x = 2
    cube.position.y = 10
    cube.position.z = 2

    cube.castShadow = true

    scene.add(cube);

    document.getElementById("WebGL-output").appendChild(renderer.domElement);
    renderer.render(scene, camera);
}
window.onload = init;
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>
<div id="WebGL-output"></div>

私はウィンドウの完全に埋められた背景として飛行機を使いたいです。

私のカメラの位置は

camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 100;

だから、それは正面から見えるものを見ています。

そして、私が飛行機の幅のサンプルとして82を設定した理由はこれです

私は camera.position.z=100; を設定し、FOV は 45度です。

だから、もし画像のように三角形を作って計算すれば、(0, 0, 0) の全幅はそのようになるだろうと思った。

私は、三角形の形と角度から計算できるあるウェブサイトから82.842…を得ます。

回答 #1

82.842 は正しいですが、PerspectiveCamera の視野角は y 軸(垂直)の角度です。
視野角を計算するには、正接(tan)を使用する必要があります。y 軸に沿った視野角は

fov_y = z * tan(angle / 2) * 2

これをコードに適用してください:

let ang_rad = 45.0 * Math.PI / 180;
let fov_y = 100 * Math.tan(ang_rad / 2) * 2;
var planeGeometry = 
    new THREE.PlaneGeometry(fov_y * window.innerWidth / window.innerHeight, fov_y);

それぞれ

let ang_rad = camera.fov * Math.PI / 180;
let fov_y = camera.position.z * Math.tan(ang_rad / 2) * 2;
var planeGeometry = new THREE.PlaneGeometry(fov_y * camera.aspect, fov_y);

焦点距離(.getFocalLength())とフィルムの高さ(.getFilmHeight())を取得することで、計算を簡略化することができます。

let fov_y = camera.position.z * camera.getFilmHeight() / camera.getFocalLength();
var planeGeometry = new THREE.PlaneGeometry(fov_y * camera.aspect, fov_y);

function init() {
    var scene = new THREE.Scene();

    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    scene.add(camera);

    camera.position.x = 0;
    camera.position.y = 0;
    camera.position.z = 100;
    camera.lookAt(scene.position); // (0, 0, 0)

    var renderer = new THREE.WebGLRenderer();
    renderer.setClearColor(new THREE.Color(0xe3e3e3));
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;

    var spotLight = new THREE.SpotLight(0xffffff);
    spotLight.position.set(50, 50, 50);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // I want to put Plane's size as full background. not (82, 82 * window.innerHeight / window.innerWidth)
    let ang_rad = camera.fov * Math.PI / 180;
    let fov_y = camera.position.z * Math.tan(ang_rad / 2) * 2;
    var planeGeometry = new THREE.PlaneGeometry(fov_y * camera.aspect, fov_y);
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0x123abc});
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.receiveShadow = true;
    plane.position.x = 0;
    plane.position.y = 0;
    plane.position.z = 0;

    scene.add(plane);

    var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
    var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
    var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

    cube.position.x = 2
    cube.position.y = 10
    cube.position.z = 2

    cube.castShadow = true

    scene.add(cube);

    document.getElementById("WebGL-output").appendChild(renderer.domElement);
    renderer.render(scene, camera);
}
window.onload = init;
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>#
<div id="WebGL-output"></div>

関連記事