溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析

發(fā)布時(shí)間:2022-08-24 11:31:01 來(lái)源:億速云 閱讀:158 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

前言

一個(gè)場(chǎng)景之所以會(huì)呈現(xiàn)在我們眼前是因?yàn)槲覀兙哂醒劬?,眼睛提供了視覺(jué)。換句話說(shuō),如果three.js場(chǎng)景中沒(méi)有這雙眼睛,就像電影沒(méi)有攝像機(jī)一樣,場(chǎng)景就無(wú)法呈現(xiàn)在我們面前?這雙眼睛就是相機(jī),可見(jiàn)相機(jī)是Three.js場(chǎng)景中不可或缺的一個(gè)組件。Three.js庫(kù)提供了兩種不同的相機(jī):正交投影相機(jī)和透視投影相機(jī),接下來(lái)分別講解這兩種相機(jī)以及結(jié)合實(shí)例的應(yīng)用。

1 正交投影相機(jī)

我們先來(lái)看一張示意圖:

three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析

由圖可知正交透視相機(jī)總共有6個(gè)面,其具備的特點(diǎn)是:場(chǎng)景中遠(yuǎn)處的物體和近處的物體是一樣大的,它并不像我們現(xiàn)實(shí)生活中看場(chǎng)景那樣,遠(yuǎn)小近大,而是遠(yuǎn)近皆一樣大;6個(gè)面分別為left(左面),right(右面),top(頂面),bottom(底面),near(近面),near(遠(yuǎn)面),右這六個(gè)面組成一個(gè)封閉的矩形空間,在這個(gè)空間內(nèi)的一切物體都可見(jiàn)。在設(shè)置其參數(shù)的時(shí)候,下面的關(guān)系式一定要成立:

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

正交相機(jī)的代碼實(shí)現(xiàn)為:

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

2 投射投影相機(jī)

投射投影相機(jī)才是現(xiàn)實(shí)世界中我們看到的場(chǎng)景的體現(xiàn):遠(yuǎn)小近大,即我們所說(shuō)的透視效果。先來(lái)看一張示意圖:

three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析

如圖中所示,透視投影相機(jī)一共有4個(gè)參數(shù):fov(視場(chǎng),一個(gè)角度值), Horizonta Field of View(橫向視場(chǎng)),Vertical

 Field of View(縱向視場(chǎng)),Near plane(近面), Far plane(遠(yuǎn)面);由這幾個(gè)因素,構(gòu)成一個(gè)六面體的封閉空間,在這個(gè)空間內(nèi)的一切物體可見(jiàn)。在設(shè)置參數(shù)時(shí),需滿足:

橫向視場(chǎng) / 縱向視場(chǎng) = 瀏覽器窗口的寬/瀏覽器窗口的高。

其代碼實(shí)現(xiàn)為:

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

3 實(shí)例

這里實(shí)現(xiàn)兩種相機(jī)的應(yīng)用,里面添加了一個(gè)簡(jiǎn)單的交互條,實(shí)現(xiàn)的效果如下圖:

three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析

three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析

本例代碼如下:

<!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">
 
    //檢測(cè)webgl的支持情況
    if(!Detector.webgl) {Detector.addGetWebGLMessage();}
    var container;
    var scene, camera, renderer;
 
 
    window.onload = function main(){
        //添加一個(gè)div元素
        container  = document.createElement('div');
        document.body.appendChild(container);
 
        //創(chuàng)建新場(chǎng)景
        scene = new THREE.Scene();
 
        //渲染
        //antialias:true增加抗鋸齒效果
        renderer = new THREE.WebGLRenderer({antialias:true});
        renderer.setClearColor(new THREE.Color(0x3399CC));//設(shè)置窗口背景顏色為黑
        renderer.setSize(window.innerWidth, window.innerHeight);//設(shè)置窗口尺寸
        //將renderer關(guān)聯(lián)到container,這個(gè)過(guò)程類似于獲取canvas元素
        container.appendChild(renderer.domElement);
 
        perCamera();
        light();
        myScene();
        render();
    };
 
    //創(chuàng)建一個(gè)透視相機(jī)
    function perCamera(){
        camera = new THREE.PerspectiveCamera(25,
            window.innerWidth/window.innerHeight, 1, 1000);
        camera.position.set(150, 180, 100);//設(shè)置相機(jī)位置
        camera.lookAt(scene.position);//讓相機(jī)指向場(chǎng)景中心
    }
 
    //創(chuàng)建一個(gè)正交投影相機(jī)
    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);//設(shè)置相機(jī)坐標(biāo)
        camera.lookAt(scene.position);//讓相機(jī)指向場(chǎng)景中心
    }
    //燈光
    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 );
    }
    //創(chuàng)建一個(gè)立體場(chǎng)景
    function myScene(){
        //創(chuàng)建平面
            var planeGeo = new THREE.PlaneGeometry(100,100,10,10);//創(chuàng)建平面
            var planeMat = new THREE.MeshLambertMaterial({  //創(chuàng)建材料
                color:0x999999,
                wireframe:false
            });
            var planeMesh = new THREE.Mesh(planeGeo, planeMat);//創(chuàng)建網(wǎng)格模型
            planeMesh.position.set(0, 0, -20);//設(shè)置平面的坐標(biāo)
            planeMesh.rotation.x = -0.5 * Math.PI;//將平面繞X軸逆時(shí)針旋轉(zhuǎn)90度
            scene.add(planeMesh);//將平面添加到場(chǎng)景中
        //創(chuàng)建立方體
            var cubeGeo1 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//創(chuàng)建立方體
            var cubeMat1 = new THREE.MeshLambertMaterial({//創(chuàng)建材料
                color:0x333333,
                wireframe:false
            });
            var cubeMesh2 = new THREE.Mesh(cubeGeo1, cubeMat1);//創(chuàng)建立方體網(wǎng)格模型
            cubeMesh2.position.set(15, 10, 0);//設(shè)置立方體的坐標(biāo)
            scene.add(cubeMesh2);//將立方體添加到場(chǎng)景中
 
            var cubeGeo2 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//創(chuàng)建立方體
            var cubeMat2 = new THREE.MeshLambertMaterial({//創(chuàng)建材料
            color:0x333333,
            wireframe:false
            });
            var cubeMesh3 = new THREE.Mesh(cubeGeo2, cubeMat2);//創(chuàng)建立方體網(wǎng)格模型
            cubeMesh3.position.set(-25, 16, 0);//設(shè)置立方體的坐標(biāo)
            scene.add(cubeMesh3);//將立方體添加到場(chǎng)景中
 
            var cubeGeo3 = new THREE.CubeGeometry(20, 40, 20, 5, 5, 5);//創(chuàng)建立方體
            var cubeMat3 = new THREE.MeshLambertMaterial({//創(chuàng)建材料
            color:0x333333,
            wireframe:false
            });
            var cubeMesh4 = new THREE.Mesh(cubeGeo3, cubeMat3);//創(chuàng)建立方體網(wǎng)格模型
            cubeMesh4.position.set(10, 20, -40);//設(shè)置立方體的坐標(biāo)
            scene.add(cubeMesh4);//將立方體添加到場(chǎng)景中
    }
 
    //添加交互工具條
    var controls = new function(){
        this.相機(jī) = false;
    };
 
    var gui = new dat.GUI();
    gui.add(controls, '相機(jī)', ["透視投影相機(jī)","正交投影相機(jī)"]).onChange(function(e){
        switch (e) {
            case "正交投影相機(jī)":
                orthCamera();
                break;
            case "透視投影相機(jī)":
                perCamera();
                break;
        }
    });
 
    function render(){
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }
</script>
</body>
</html>

讀到這里,這篇“three.js中正交與透視投影相機(jī)應(yīng)用實(shí)例分析”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI