Three.js相机

  在Threejs中相机的表示是THREE.Camera,它是相机的抽象基类,其子类有两种相机,分别是正投影相机THREE.OrthographicCamera和透视投影相机THREE.PerspectiveCamera。

  正投影和透视投影的区别是:透视投影有一个基本点,就是远处的物体比近处的物体小。而正投影远近高低比例都相同。

【注】正投影和透视投影的显示方面的区别:比如有一个正方体,使用正投影则只能看到面向自己的那一面正方形,而使用透视投影则看起来是个正方形,因为远处的比近处的大。

一、正投影相机

  正投影的构造函数如下所示:

OrthographicCamera( left, right, top, bottom, near, far )

  结合下面一个图,我们来看看,各个参数的意思。

  • left:左平面距离相机中心点的垂直距离。从图中可以看出,左平面是屏幕里面的那个平面。
  • right:右平面距离相机中心点的垂直距离。从图中可以看出,右平面是屏幕稍微外面一点的那个平面。
  • top:顶平面距离相机中心点的垂直距离。上图中的顶平面,是长方体头朝天的平面。
  • bottom:底平面距离相机中心点的垂直距离。底平面是头朝地的平面。
  • near:近平面距离相机中心点的垂直距离。近平面是左边竖着的那个平面。
  • far:远平面距离相机中心点的垂直距离。远平面是右边竖着的那个平面。

  有了这些参数和相机中心点,我们这里将相机的中心点又定义为相机的位置。通过这些参数,我们就能够在三维空间中唯一的确定上图的一个长方体。这个长方体也叫做视景体。投影变换的目的就是定义一个视景体,使得视景体外多余的部分裁剪掉,最终图像只是视景体内的有关部分。

好了,看一个简单的例子:

var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
scene.add( camera );

  这个例子将浏览器窗口的宽度和高度作为了视景体的高度和宽度,相机正好在窗口的中心点上。这也是我们一般的设置方法,基本上为了方便,我们不会设置其他的值。

二、透视投影相机 

  透视投影相机的构造函数如下所示:

PerspectiveCamera( fov, aspect, near, far )

如图所示:

  • 视角fov:可以理解为眼睛睁开的角度,即,视角的大小,如果设置为0,相当你闭上眼睛了,所以什么也看不到,如果为180,那么可以认为你的视界很广阔,但是在180度的时候,往往物体很小,因为他在你的整个可视区域中的比例变小了。
  • 近平面near:这个呢,表示你近处的裁面的距离。补充一下,也可以认为是眼睛距离近处的距离。
  • 远平面far:这个呢,表示你远处的裁面。
  • 纵横比aspect:实际窗口的纵横比,即宽度除以高度。这个值越大,说明你宽度越大,那么你可能看的是宽银幕电影了,如果这个值小于1,那么可能你看到的是如下的图中的LED屏幕了。

例子如下所示:

var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
scene.add( camera );

三、例子

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Three框架</title>
        <script src="js/Three.js"></script>
        <style type="text/css">
            div#canvas-frame {
                border: none;
                cursor: pointer;
                width: 100%;
                height: 600px;
                background-color: #EEEEEE;
            }

        </style>
        <script>
            var renderer;
            function initThree() {
                width = document.getElementById('canvas-frame').clientWidth;
                height = document.getElementById('canvas-frame').clientHeight;
                renderer = new THREE.WebGLRenderer({
                    antialias : true
                });
                renderer.setSize(width, height);
                document.getElementById('canvas-frame').appendChild(renderer.domElement);
                renderer.setClearColor(0xFFFFFF, 1.0);
            }

            var camera;
            function initCamera() {
                camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
                //camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 10, 1000 );
                camera.position.x = 0;
                camera.position.y = 0;
                camera.position.z = 600;
                camera.up.x = 0;
                camera.up.y = 1;
                camera.up.z = 0;
                camera.lookAt({
                    x : 0,
                    y : 0,
                    z : 0
                });
            }

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

            var light;
            function initLight() {
                light = new THREE.AmbientLight(0xFF0000);
                light.position.set(100, 100, 200);
                scene.add(light);
                
                light = new THREE.PointLight(0x00FF00);
                light.position.set(0, 0,300);
                scene.add(light);
            }

            var cube;
            function initObject() {
                var geometry = new THREE.CylinderGeometry( 70,100,200);
                var material = new THREE.MeshLambertMaterial( { color:0xFFFFFF} );
                var mesh = new THREE.Mesh( geometry,material);
                mesh.position = new THREE.Vector3(0,0,0);
                scene.add(mesh);
            }

            function threeStart() {
                initThree();
                initCamera();
                initScene();
                initLight();
                initObject();
                animation();

            }
            function animation()
            {
                changeFov();
                renderer.render(scene, camera);
                requestAnimationFrame(animation);
            }
            
            function setCameraFov(fov)
            {
                camera.fov = fov;
                camera.updateProjectionMatrix();
            }
            
            function changeFov()
            {
                var txtFov = document.getElementById("txtFov").value;
                var val = parseFloat(txtFov);
                setCameraFov(val);
            }
        </script>
    </head>

    <body onload="threeStart();">
        <div id="canvas-frame"></div>
        <div>
            Fov:<input type="text" value="45" id="txtFov"/>(0到180的值)
        </div>
    </body>
</html>

 

posted @ 2018-05-23 14:01  麦田里的小王子  阅读(452)  评论(0编辑  收藏  举报