【问题标题】:Three.js set plane size to full viewThree.js 将平面大小设置为全视图
【发布时间】:2020-06-08 09:39:36
【问题描述】:

我是日本人,英语不好,抱歉。

我正在学习 Three.js。

我想将平面设置为相机正前方的背景。

我希望平面背景完全填满窗口(渲染器)。

但现在是这样的。

飞机是蓝色的。

有点小。

这里是代码。

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 设置为 Plane 的宽度样本的原因是这样的

我设置了camera.position.z = 100;,fov 是 45 度。

所以我想如果你制作一个像图像一样的三角形并计算,(0, 0, 0) 的全宽应该是这样的。

我从某个网站获得 82.842...,该网站可以根据 is 的形状和度数计算三角形。

【问题讨论】:

    标签: javascript html typescript three.js


    【解决方案1】:

    82.842是正确的,但是PerspectiveCamera的视野角度是y轴(垂直)上的角度。
    要计算视野,您必须使用tangents (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>

    【讨论】:

    • 天哪。你真棒。非常感谢。
    • "but the field of view angle of the PerspectiveCamera is the angle on the y-axis (vertical)"我不知道,非常感谢。
    • let fov_y = 100 * Math.tan(ang_rad / 2) * 2 这样做的原因是,将三角形切成两半,然后将半个三角形的高度乘以 tan 并将其加倍,这样写?
    • @Akao 是的,半三角形是Right triangle。切线(乘以 Z)得出半高。
    • 谢谢!你拯救了我的一天
    猜你喜欢
    • 2019-04-06
    • 2012-08-27
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多