温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

three.js中正交与透视投影相机应用实例分析

发布时间:2022-08-24 11:31:01 来源:亿速云 阅读:165 作者:iii 栏目:开发技术

本文小编为大家详细介绍“three.js中正交与透视投影相机应用实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“three.js中正交与透视投影相机应用实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

前言

一个场景之所以会呈现在我们眼前是因为我们具有眼睛,眼睛提供了视觉。换句话说,如果three.js场景中没有这双眼睛,就像电影没有摄像机一样,场景就无法呈现在我们面前?这双眼睛就是相机,可见相机是Three.js场景中不可或缺的一个组件。Three.js库提供了两种不同的相机:正交投影相机和透视投影相机,接下来分别讲解这两种相机以及结合实例的应用。

1 正交投影相机

我们先来看一张示意图:

three.js中正交与透视投影相机应用实例分析

由图可知正交透视相机总共有6个面,其具备的特点是:场景中远处的物体和近处的物体是一样大的,它并不像我们现实生活中看场景那样,远小近大,而是远近皆一样大;6个面分别为left(左面),right(右面),top(顶面),bottom(底面),near(近面),near(远面),右这六个面组成一个封闭的矩形空间,在这个空间内的一切物体都可见。在设置其参数的时候,下面的关系式一定要成立:

| left / right | = 1,top / buttom | = 1

正交相机的代码实现为:

var camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);

2 投射投影相机

投射投影相机才是现实世界中我们看到的场景的体现:远小近大,即我们所说的透视效果。先来看一张示意图:

three.js中正交与透视投影相机应用实例分析

如图中所示,透视投影相机一共有4个参数:fov(视场,一个角度值), Horizonta Field of View(横向视场),Vertical

 Field of View(纵向视场),Near plane(近面), Far plane(远面);由这几个因素,构成一个六面体的封闭空间,在这个空间内的一切物体可见。在设置参数时,需满足:

横向视场 / 纵向视场 = 浏览器窗口的宽/浏览器窗口的高。

其代码实现为:

var camera = new THREE.PerspectiveCamera(fov, width / height, near, far);

3 实例

这里实现两种相机的应用,里面添加了一个简单的交互条,实现的效果如下图:

three.js中正交与透视投影相机应用实例分析

three.js中正交与透视投影相机应用实例分析

本例代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>threejs-camera</title>
    <style>
        body{
            font-family: Monospace;
            backgroud: #f0f0f0;
            margin: 0px;
            overflow: hidden;
        }
    </style>
</head>
<body>
<script type="text/javascript" src="build/three.js"></script>
<script type="text/javascript" src="js/Detector.js"></script>
<script type="text/javascript" src="js/libs/dat.gui.min.js"></script>
<script type="text/javascript">
 
    //检测webgl的支持情况
    if(!Detector.webgl) {Detector.addGetWebGLMessage();}
    var container;
    var scene, camera, renderer;
 
 
    window.onload = function main(){
        //添加一个div元素
        container  = document.createElement('div');
        document.body.appendChild(container);
 
        //创建新场景
        scene = new THREE.Scene();
 
        //渲染
        //antialias:true增加抗锯齿效果
        renderer = new THREE.WebGLRenderer({antialias:true});
        renderer.setClearColor(new THREE.Color(0x3399CC));//设置窗口背景颜色为黑
        renderer.setSize(window.innerWidth, window.innerHeight);//设置窗口尺寸
        //将renderer关联到container,这个过程类似于获取canvas元素
        container.appendChild(renderer.domElement);
 
        perCamera();
        light();
        myScene();
        render();
    };
 
    //创建一个透视相机
    function perCamera(){
        camera = new THREE.PerspectiveCamera(25,
            window.innerWidth/window.innerHeight, 1, 1000);
        camera.position.set(150, 180, 100);//设置相机位置
        camera.lookAt(scene.position);//让相机指向场景中心
    }
 
    //创建一个正交投影相机
    function orthCamera(){
        camera = new THREE.OrthographicCamera(window.innerWidth/-14.5,window.innerWidth/14.5,
           window.innerHeight/14.5,window.innerHeight/-14.5,-100,400);
        camera.position.set(150,180, 100);//设置相机坐标
        camera.lookAt(scene.position);//让相机指向场景中心
    }
    //灯光
    function light(){
        //自然光
        var ambientLight = new THREE.AmbientLight( 0x606060 );
        scene.add( ambientLight );
 
        //平行光源
        var directionalLight = new THREE.DirectionalLight( 0xffffff );
        directionalLight.position.set( 1, 1.75, 0.5 ).normalize();
        scene.add( directionalLight );
    }
    //创建一个立体场景
    function myScene(){
        //创建平面
            var planeGeo = new THREE.PlaneGeometry(100,100,10,10);//创建平面
            var planeMat = new THREE.MeshLambertMaterial({  //创建材料
                color:0x999999,
                wireframe:false
            });
            var planeMesh = new THREE.Mesh(planeGeo, planeMat);//创建网格模型
            planeMesh.position.set(0, 0, -20);//设置平面的坐标
            planeMesh.rotation.x = -0.5 * Math.PI;//将平面绕X轴逆时针旋转90度
            scene.add(planeMesh);//将平面添加到场景中
        //创建立方体
            var cubeGeo1 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体
            var cubeMat1 = new THREE.MeshLambertMaterial({//创建材料
                color:0x333333,
                wireframe:false
            });
            var cubeMesh2 = new THREE.Mesh(cubeGeo1, cubeMat1);//创建立方体网格模型
            cubeMesh2.position.set(15, 10, 0);//设置立方体的坐标
            scene.add(cubeMesh2);//将立方体添加到场景中
 
            var cubeGeo2 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体
            var cubeMat2 = new THREE.MeshLambertMaterial({//创建材料
            color:0x333333,
            wireframe:false
            });
            var cubeMesh3 = new THREE.Mesh(cubeGeo2, cubeMat2);//创建立方体网格模型
            cubeMesh3.position.set(-25, 16, 0);//设置立方体的坐标
            scene.add(cubeMesh3);//将立方体添加到场景中
 
            var cubeGeo3 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体
            var cubeMat3 = new THREE.MeshLambertMaterial({//创建材料
            color:0x333333,
            wireframe:false
            });
            var cubeMesh4 = new THREE.Mesh(cubeGeo3, cubeMat3);//创建立方体网格模型
            cubeMesh4.position.set(10, 20, -40);//设置立方体的坐标
            scene.add(cubeMesh4);//将立方体添加到场景中
    }
 
    //添加交互工具条
    var controls = new function(){
        this.相机 = false;
    };
 
    var gui = new dat.GUI();
    gui.add(controls, '相机', ["透视投影相机","正交投影相机"]).onChange(function(e){
        switch (e) {
            case "正交投影相机":
                orthCamera();
                break;
            case "透视投影相机":
                perCamera();
                break;
        }
    });
 
    function render(){
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }
</script>
</body>
</html>

读到这里,这篇“three.js中正交与透视投影相机应用实例分析”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI