Three.js将平面大小设置为全屏视图。

4
我是日本人,不擅长英语,抱歉。
我正在学习Three.js。
我想将Plane设置为相机正前方的背景。
而且我希望Plane背景完全填充窗口(渲染器)。
但现在它是这样的。
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个回答

5

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>


哇塞,你真棒。非常感谢你。 - Akao
但是PerspectiveCamera的视野角度是沿着y轴(垂直方向)的角度。我之前并不知道,非常感谢你。 - Akao
让 fov_y = 100 * Math.tan(ang_rad / 2) * 2,原因是将三角形切成两半,通过正切获取半个三角形的高度并将其加倍,写对了吗? - Akao
@Akao 是的,半三角形是一个直角三角形。正切(乘以Z)给出了半高度。 - Rabbid76
1
谢谢!你救了我的一天。 - Khal91

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接