前言

一个场景之所以会呈现在我们眼前是因为我们具有眼睛,眼睛提供了视觉。换句话说,如果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正交与透视投影相机内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

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

  1. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  2. ios – 如何将视频从AVAssetExportSession保存到相机胶卷?

    在此先感谢您的帮助.解决方法只需使用session.outputURL=…

  3. ios – 仅使用AVFoundation播放相机声音一次以获得多张图像或简单地以编程方式静音/抑制声音

    对于Question1,Question2,Question3,我在同一个平台上也有类似的问题.我使用AVFoundation捕获多个图像(5个图像–1.5秒的爆破模式),我可以成功捕获5个图像,但每次拍摄新图像时都会制作快门声.我正在为静态图像使用captureStillImageAsynchronouslyFromConnection.图像质量/清晰度是我的主要焦点,我不想妥协图像质量和图像捕

  4. ios – 根据UIView / CGRect的大小将图像裁剪成正方形

    我有AVCaptureSession的实现,我的目标是让用户拍摄照片,只将图像的一部分保存在红色方块边框内,如下图所示:AVCaptureSession的previewLayer(相机)从(0,0)(左上角)跨越到我的相机控制栏(位于包含快门的视图的正上方)的底部.我的导航栏和控制栏是半透明的,所以相机可以显示.我正在使用[captureSessionsetSessionPreset:AVCapt

  5. Ios在Xcode中创建简单的相机叠加如何?

    我应该使用什么类,我该怎么办?

  6. ios – SpriteKit:我应该平移相机还是移动背景?

    使用SpriteKit构建游戏时,使用平台游戏,是否最好将相机向上移动,或者将背景节点向下移动?其他框架的标准做法是什么?关于2D游戏引擎最令人费解的事情之一就是它通常需要一系列版本才能获得相机.他们应该和他们一起出生.SpriteKit也不例外,它需要永远拿到相机.现在它有一个,从来没有想过不使用它.会让你的生活变得简单一百万倍.我可以想到没有例外,但期待被证明是错误的.

  7. iOS保存照片到相机胶卷不会保留EXIF / GPS元数据

    编辑:我想我应该更具体一点.目的是将现有JPEG文件的副本保存到用户的相机胶卷中.最有效的方法是什么?

  8. 不同iOS相机的图像尺寸?

    我正在我的应用中创建一个功能,让人们可以在设备相机中拍照,并在拍摄的图像上方添加一个叠加层.我是通过将从相机接收的图像与其他叠加图像合并来实现的.我知道在iPhone4上,相机图像是1936x2592.所以我准备了相同尺寸的叠加图像.我想知道其他设备的图像尺寸是否不同?

  9. ios – 在iphone中减少相机/照片库图像文件大小不到100 KB

    缩小它:

  10. ios – 使用OpenGL的神秘app崩溃

    我正在使用GPUIImage库来开发iOS相机应用程序.有时,当应用程序在2-3分钟后暂停时,Xcode会在应用程序上发生崩溃,指向方法中的行:可能是这次崩溃的原因是什么?我有一个非常长的摄像头设置,代码本身在GPUImageContext类中.我在这里做错了什么?

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部