Three.js入門詳解


什么是WebGL

   WebGL(Web 圖形庫)是一種 JavaScript API,用於在任何兼容的 Web 瀏覽器中呈現交互式 3D 和 2D 圖形,而無需使用插件。WebGL 通過引入一個與 OpenGL ES 2.0 緊密相符合的 API,可以在 HTML5 <canvas> 元素中使用(簡介引自 MDN)。

  以我的理解,WebGL 給我們提供了一系列的圖形接口,能夠讓我們通過 JavaScript 去使用 GPU 來進行瀏覽器圖形渲染的工具。

什么是Three.js

   Three.js 是一款 webGL 框架,由於其易用性被廣泛應用。Three.js 在 WebGL 的 API 接口基礎上,又進行的一層封裝。它是由居住在西班牙巴塞羅那的程序員 Ricardo Cabbello Miguel 所開發,他更為人知的網名是 Mr.doob。 

  Three.js 以簡單、直觀的方式封裝了 3D 圖形編程中常用的對象。Three.js 在開發中使用了很多圖形引擎的高級技巧,極大地提高了性能。另外,由於內置了很多常用對象和極易上手的工具,Three.js 的功能也非常強大。最后,Three.js 還是完全開源的,你可以在 GitHub 上找到它的源代碼,並且有很多人貢獻代碼,幫助 Mr.doob 一起維護這個框架。

WebGL與Three.js的關系

  WebGL 原生 API 是一種非常低級的接口,而且還需要一些數學和圖形學的相關技術。對於沒有相關基礎的人來說,入門真的很難,Three.js 將入門的門檻降低了一大截,對 WebGL 進行封裝,簡化我們創建三維動畫場景的過程。只要你有一定的 JavaScript 基礎,有一定的前端經驗,我堅信,用不了多長時間,三維制作會變得很簡單。

  用最簡單的一句話概括:WebGL 和 Three.js 的關系,相當於 JavaScript 和 jQuery 的關系。

功能概述

Three.js 作為 WebGL 框架中的佼佼者,由於它的易用性和擴展性,使得它能夠滿足大部分的開發需求,Three.js 的具體功能如下:

  1. Three.js 掩蓋了 3D 渲染的細節:Three.js 將 WebGL 原生 API 的細節抽象化,將 3D 場景拆解為網格、材質和光源(即它內置了圖形編程常用的一些對象種類)。

  2. 面向對象:開發者可以使用上層的 JavaScript 對象,而不是僅僅調用 JavaScript 函數。

  3. 功能非常豐富:Three.js 除封裝了 WebGL 原始 API 之外,Three.js 還包含了許多實用的內置對象,可以方便地應用於游戲開發、動畫制作、幻燈片制作、髙分辨率模型和一些特殊的視覺效果制作。

    4. 速度很快:Three.js 采用了 3D 圖形最佳實踐來保證在不失可用性的前提下,保持極高的性能。

  5. 支持交互:WebGL 本身並不提供拾取(Picking)功能(即是否知道鼠標正處於某個物體上)。而 Three.js 則固化了拾取支持,這就使得你可以輕松為你的應用添加交互功能。

  6. 包含數學庫:Three.js 擁有一個強大易用的數學庫,你可以在其中進行矩陣、投影和矢量運算。

  7. 內置文件格式支持:你可以使用流行的 3D 建模軟件導出文本格式的文件,然后使用 Three.js 加載,也可以使用 Three.js 自己的 JSON 格式或二進制格式。

  8. 擴展性很強:為 Three.js 添加新的特性或進行自定義優化是很容易的事情。如果你需要某個特殊的數據結構,那么只需要封裝到 Three.js 即可。

  9. 支持HTML5 Canvas:Three.js 不但支持 WebGL,而且還支持使用 Canvas2D、Css3D 和 SVG 進行渲染。在未兼容 WebGL 的環境中可以回退到其它的解決方案。

雖然 Three.js 的優勢很大,但是它也有它的不足之處:

  1. 官網文檔非常粗糙,對於新手極度不友好。

  2. 國內的相關資源匱乏。

  3. Three.js 所有的資料都是以英文格式存在,對國內的朋友來說又提高了門檻。

  4. Three.js 不是游戲引擎,一些游戲相關的功能沒有封裝在里面,如果需要相關的功能需要進行二次開發。

Three.js提供了幾種源碼獲取方式,我是用的BootCDN 提供的免費 CDN 加速服務(同時支持 HTTP 和 HTTPS 協議),直接引入方式為:

<script src="https://cdn.bootcss.com/three.js/r83/three.js"></script>

如果需要更新代碼,可以點擊這里查找最新版本地址引入即可。

入門程序:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
<!--    引入three.js-->
    <script src="https://cdn.bootcss.com/three.js/r83/three.js"></script>
<!--    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script>-->
    <title>a</title>
    <style>
        /* 將margin設為0,overflow設為hidden,全屏顯示 */
        body {
            margin: 0;
            overflow: hidden;  /* 超出部分隱藏 */
        }
    </style>
</head>
<body>
<div id="webgl-output"></div>

<script type="text/javascript">
    // 一旦所有東西都被加載,我們運行我們的Three.js東西
    function init() {
        // 創建一個場景,其中包含所有元素,如對象、相機和燈光
        var scene = new THREE.Scene();
        // 創建一個攝像頭,它定義了我們看的地方
        // PerspectiveCamera(透視攝像機)、第一個屬性是視野角度(FOV)、第二個值是長寬比(aspect ratio)、接下來的兩個值是遠剪切面和近剪切面
        var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
        // 創建一個渲染器(負責計算指定相機角度下瀏覽器中scene的樣子)和設置大小
        var renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));  // 將renderer對象的背景色設置為0xEEEEEE
        renderer.setSize(window.innerWidth, window.innerHeight);  // 讓renderer對象將scene渲染成多大的尺寸
        renderer.shadowMapEnabled = true;  // 告訴渲染器需要陰影⭐️
        // 在屏幕中顯示軸
        // var axes = new THREE.AxisHelper(20);  // axes坐標軸對象
        // scene.add(axes);  // 把坐標軸添加到場景中去
        // 創建接地面
        var planeGeometry = new THREE.PlaneGeometry(60, 20);  // PlaneGeometry: 平面幾何 (參數: 寬60, 高20)
        var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});  // // MeshLambertMaterial:網格材質 (用來設置平面的外觀, 顏色,透明度等)
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);  // 把這2個對象合並到一個名為plane(平面)的Mesh(網格)對象中
        // 旋轉並定位平面
        plane.receiveShadow = true;  // 平面接收陰影⭐️
        plane.rotation.x = -0.5 * Math.PI;  // 繞X軸旋轉90度
        plane.position.x = 15;  // 平面坐標位置
        plane.position.y = 0;
        plane.position.z = 0;
        scene.add(plane);  // 把平面添加到場景
        // 創建一個立方體
        var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);  // 立方體幾何
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});  // 立方體材質(顏色、wireframe: true線框)
        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);  // 立方體和外觀合並
        cube.castShadow = true;  // 立方體陰影⭐️
        cube.position.x = -4;  // 立方體的坐標位置
        cube.position.y = 3;
        cube.position.z = 0;
        scene.add(cube);  //把立方體添加到場景
        // 創建一個球體
        var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);  // 球體
        var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});  // 球體的外觀(顏色、wireframe: true線框)
        var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);  // 球體與外觀合並
        sphere.castShadow = true;  // 球體的陰影
        sphere.position.x = 20;  // 球體的位置
        sphere.position.y = 4;
        sphere.position.z = 2;
        scene.add(sphere);  // 把圓添加到場景
        // 將攝像機定位並指向場景中心
        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);  // lookAt函數指向場景的位置
        // 添加一個光源⭐️
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;    // 讓光源產生陰影
        scene.add(spotLight);
        // 將渲染器的輸出添加到html元素中
        document.getElementById('webgl-output').appendChild(renderer.domElement);
        // 渲染的場景
        renderer.render(scene, camera)
    }
    window.onload = init;
</script>
</body>
</html>

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM