【问题标题】:How to determine the 3D boundaries of camera field of view in three.js如何在three.js中确定相机视野的3D边界
【发布时间】:2016-04-24 04:55:56
【问题描述】:

我有一个 three.js 场景,想知道视口的 3D 边界。

例如,假设我有一个 500 像素宽和 1000 像素高的画布。我的相机正在查看位置 { 0, 0, 0 } 并且在位置 { 0, 0, 100 };

我的相机永远不会移动。

假设我有一个位于{ 0, 0, 0 } 的对象。我需要能够将该对象移动到可视区域内(相机视野内)的各个点。例如,我如何计算相机视野的上/左角?另外,如何计算相机视野左侧的 20% 和顶部的 10%?

这是我的相机对象:

{
    "object": {
        "uuid": "E26C5F88-CD17-45F8-A492-F3DD704949BF",
        "type": "PerspectiveCamera",
        "matrix": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 100, 1],
        "zoom": 1,
        "fov": 50,
        "aspect": 0.625,
        "near": 0.1,
        "far": 1000
    }
}

【问题讨论】:

    标签: javascript 3d three.js


    【解决方案1】:

    要将对象放置在距左侧 20% 处,从顶部向下 10% 处,您可以使用如下方式:

    var left = 0.2;
    var top = 0.1;
    var depth = 0.7; // from -1 to 1, depends how far into the scene you want the object, -1 being very close, 1 being the furthest away the camera can see
    object.position.set( -1 + 2 * left, 1 - 2 * top, depth ).unproject( camera );
    

    这会将位于 [-1, 1] 范围内的 NDC(标准化设备坐标)中的位置转换为世界坐标。

    它本质上是下面图像 (source) 的逆操作,并将右侧图像 (NDC) 中的一个点转换回左侧图像(世界坐标):

    例如:

    var canvas = document.getElementById('canvas');
    var scene = new THREE.Scene();
    var renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true});
    var camera = new THREE.PerspectiveCamera(45, canvas.clientWidth / canvas.clientWidth, 1, 1000);
    var clock = new THREE.Clock();
    
    var geometry = new THREE.BoxGeometry(1, 1, 1);
    var material = new THREE.MeshBasicMaterial({color: '#f00', wireframe: true});
    var box = new THREE.Mesh(geometry, material);
    
    scene.add(box);
    
    var period = 5;
      
    var top = 0.3; // 30%
    var left = 0.2; // 20%
    var depth = 0.7;
    
    render();
    
    function render() {
      requestAnimationFrame(render);
      
      if (canvas.width !== canvas.clientWidth || canvas.height !== canvas.clientHeight) {
        renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
        camera.aspect = canvas.clientWidth /  canvas.clientHeight;
        camera.updateProjectionMatrix();
      }
      
      box.position.set(-1 + 2 * left, 1 - 2 * top, depth).unproject(camera);
      box.rotation.y += clock.getDelta() * 2 * Math.PI / period;
      
      renderer.render(scene, camera);
    }
    html, body, canvas {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
        display: block;
    }
    <script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
    <canvas id="canvas"></canvas>

    【讨论】:

    • 很好,彻底的答案。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 2016-10-15
    • 2015-06-27
    • 1970-01-01
    • 2017-02-20
    • 2016-05-02
    相关资源
    最近更新 更多