three.js中正交与透视投影相机的实战应用指南

目录
  • 前言
  • 1 正交投影相机
  • 2 投射投影相机
  • 3 实例
  • 总结

前言

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

1 正交投影相机

我们先来看一张示意图:

由图可知正交透视相机总共有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 投射投影相机

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

如图中所示,透视投影相机一共有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 实例

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

本例代码如下:

<!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 cubeMesh1 = new THREE.Mesh(cubeGeo1, cubeMat1);//创建立方体网格模型
            cubeMesh1.position.set(15, 10, 0);//设置立方体的坐标
            scene.add(cubeMesh1);//将立方体添加到场景中

            var cubeGeo2 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体
            var cubeMat2 = new THREE.MeshLambertMaterial({//创建材料
            color:0x333333,
            wireframe:false
            });
            var cubeMesh2 = new THREE.Mesh(cubeGeo2, cubeMat2);//创建立方体网格模型
            cubeMesh2.position.set(-25, 16, 0);//设置立方体的坐标
            scene.add(cubeMesh2);//将立方体添加到场景中

            var cubeGeo3 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//创建立方体
            var cubeMat3 = new THREE.MeshLambertMaterial({//创建材料
            color:0x333333,
            wireframe:false
            });
            var cubeMesh3 = new THREE.Mesh(cubeGeo3, cubeMat3);//创建立方体网格模型
            cubeMesh3.position.set(10, 20, -40);//设置立方体的坐标
            scene.add(cubeMesh3);//将立方体添加到场景中
    }

    //添加交互工具条
    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中正交与透视投影相机的文章就介绍到这了,更多相关three.js正交与透视投影相机内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Three.js学习之正交投影照相机

    前言 Three.js是一个3Djs库,webGL开源框架中比较优秀的一个.除了webGL以外,Three.js还提供了基于Canvas.SVG标签的渲染器,调试建议使用Chrome或者Firefox. 1.照相机 图形学中的照相机定义了三维空间到二维屏幕的投影方式. 针对投影方式照相机分为正交投影照相机和透视投影照相机. 2.两种相机的区别与适用范围 正交投影: 透视投影: 正交投影就像数学课上画的:而透视投影有一个基本点,就是远处的物体比近处的物体小,远大近小. 对于制图.建模软件通常使用正

  • three.js中正交与透视投影相机的实战应用指南

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

  • js中区分深拷贝与浅拷贝的实战过程

    目录 一.自我理解 二.数据存储形式 (1)基本数据类型存储于栈中 (2)引用数据类型存储与堆中 三.怎样实现深拷贝? (1)借助JSON对象的parse和stringify (2)手写递归 (3)JQuery中extend方法 总结/注意 总结 一.自我理解 简单来讲就是:深拷贝层层拷贝,浅拷贝只拷贝第一层. 在深拷贝中,新对象中的更改不会影响原对象,而在浅拷贝中,新对象中的更改,原对象中也会跟着改. 在深拷贝中,原对象与新对象不共享相同的属性,而在浅拷贝中,它们具有相同的属性. 举个栗子:存

  • Three.js中矩阵和向量的使用教程

    前言 提起矩阵,很容易让人想起我们曾经学不会的线性代数和离散数学,但是作为图形开发中的核心部分,它代表着每一次的运动和变换,就像鱼不能脱离水一样,矩阵并不是一个可以避之不谈的话题. 好消息是,Three.js帮助我们把许多矩阵运算封装成了一些顶层的方法,并提供了一个优秀的数学库,我们不太需要知道HowToCalc,只需要知道HowToUse,就可以得到绝大部分我们想要的东西. 这篇文章将要介绍的就是,如何在不了解内部结构的情况下在Three.js中使用矩阵和向量. 从一个例子开始 在讲解一些枯燥

  • Angular.js中window.onload(),$(document).ready()的写法浅析

    一,问题发现: 最近公司有个微信公众号项目,为了方便直接使用anular.js+ionic进行开发,里面有使用到echarts图表,具体开发中发现echarts在初始化绑定图表的DOM节点时,一直提示该节点不合法;可是明明已经把代码写在了window.onload()中了,又改成$(function(){})结果还是不行. 二,解决方案 1使用angular.element <script type="text/javascript"> angular.element(wi

  • Angular.js中数组操作的方法教程

    前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢.最近在学习Angular.js,将自己学习的一些经验技巧分享给大家,下面本文将给大家介绍关于Angular.js中数组操作的相关资料,话不多说了,来一起看看详细的介绍. 1:ng-click,ng-model,ng-bind,ng-class,ng-hide,ng-app 2:placeholder, 3:{}中加入代码":true|false",使用逗号隔开,可以

  • Angular.js中$resource高大上的数据交互详解

    本文主要给大家介绍的是关于Angular.js中$resource数据交互的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: $resource 创建一个resource对象的工厂函数,可以让你安全的和RESFUL服务端进行数据交互. 需要注入 ngResource 模块.angular-resource[.min].js 默认情况下,末尾斜杠(可以引起后端服务器不期望出现的行为)将从计算后的URL中剥离. 这个可以通过$resourceProvider配置: app.config(

  • Angular.js中控制器之间的传值详解

    前言 每个controller都会有自己的scope,所有的scope都是属于 $rootScope的子或者子的子... 那么问题就好解决了,通过 $rootScope.$broadcast 广播的事件每个controller都能收到事件 另外,我的经验是,尽量不要用event传数据.应该建立一个service来保存数据,并且设置相应getter/setter,具体如下: 每个controller依赖service, call service.setter(...) 统一的service.set

  • 深入浅析js中的正则表达式

    阅读目录 正则表达式的创建 正则表达式中的特殊字符 \ (反斜杠) ^ $ *,  +,  .(小数点) ? (问号) (x) (?:x) x(?=y), x(?!y), x|y {n}, {n,m}: [xyz], [^xyz] 其他 正则表达式标志 正则表达式使用 很多时候多会被正则表达式搞的晕头转向,最近抽出时间对正则表达式进行了系统的学习,整理如下: 正则表达式的创建 两种方法,一种是直接写,由包含在斜杠之间的模式组成:另一种是调用RegExp对象的构造函数. 两种方法的创建代码如下:

  • js中settimeout方法加参数

    js中settimeout方法加参数的使用.简单使用看w3school 里面没有参数调用, 例子: 复制代码 代码如下: <script type="text/javascript"> function timedMsg() { var a ="dd"; var t=setTimeout(function(){ cao(a);},3000) } function cao(a) { alert(a); } </script> </head

  • 使用JS中的exec()方法构造正则表达式验证

    正则表达式,又称正规表示法.常规表示法.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则.在很多文本编辑器里,正则表达式通常被用来检索.替换那些符合某个模式的文本. 一.Javascript中的正则表达式 在Javascript中,可以使用RegExp对象构造正则表达.我们需要新建一个实例化的RegExp()对象,可以传入两个参数:第一个参数是匹配的模式,第二个参数是一

随机推荐