<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          WebGL 概念和基礎(chǔ)入門(mén)

          共 13689字,需瀏覽 28分鐘

           ·

          2021-08-13 10:06

          本文首發(fā)于政采云前端團(tuán)隊(duì)博客:WebGL 概念和基礎(chǔ)入門(mén)

          https://www.zoo.team/article/webglabout

          WebGL 是什么

          對(duì)于 WebGL 百度百科給出的解釋是 WebGL 是一種 3D 繪圖協(xié)議,而對(duì)此維基百科給出的解釋卻是一種 JavaScript API。由于 WebGL 技術(shù)旨在幫助我們?cè)诓皇褂貌寮那闆r下在任何兼容的網(wǎng)頁(yè)瀏覽器中開(kāi)發(fā)交互式 2D 和 3D 網(wǎng)頁(yè)效果,我們可以將其理解為一種幫助我們開(kāi)發(fā) 3D 網(wǎng)頁(yè)的繪圖技術(shù),當(dāng)然底層還是 JavaScript API。

          WebGL 發(fā)展史

          WebGL 的發(fā)展最早要追溯到 2006 年,WebGL 起源于 Mozilla 員工弗拉基米爾·弗基西維奇的一項(xiàng) Canvas 3D 實(shí)驗(yàn)項(xiàng)目,并于 2006 年首次展示了 Canvas 3D 的原型。這一技術(shù)在 2007 年底在 FireFox 和 Opera 瀏覽器中實(shí)現(xiàn)。2009 年初 Khronos Group 聯(lián)盟創(chuàng)建了 WebGL 的工作組最初的工作成員包括 Apple、Google、Mozilla、Opera 等。2011 年 3 月 WebGL 1.0 規(guī)范發(fā)布,WebGL 2 規(guī)范的發(fā)展始于 2013 年,并于 2017 年 1 月最終完成,WebGL 2 的規(guī)范,首度在 Firefox 51、Chrome 56 和 Opera 43 中被支持。

          WebGL 中的基本概念

          WebGL 運(yùn)行在電腦的 GPU 中,因此需要使用能在 GPU 上運(yùn)行的代碼,這樣的代碼需要提供成對(duì)的方法,每對(duì)方法中的一個(gè)叫頂點(diǎn)著色器而另外一個(gè)叫做片元著色器,并且使用 GLSL 語(yǔ)言。將頂點(diǎn)著色器和片元著色器連接起來(lái)的方法叫做著色程序。

          • 頂點(diǎn)著色器:頂點(diǎn)著色器的作用是計(jì)算頂點(diǎn)的位置,即提供頂點(diǎn)在裁剪空間中的坐標(biāo)值
          • 片元著色器:片元著色器的作用是計(jì)算圖元的顏色值,我們可以將片元著色器大致理解成網(wǎng)頁(yè)中的像素
          • 數(shù)據(jù)獲取方式:在前面我們提到了頂點(diǎn)著色器和片元著色器的概念,而頂點(diǎn)著色器和片元著色器這兩個(gè)方法的運(yùn)行都需要有對(duì)應(yīng)的數(shù)據(jù),接下來(lái)我們一起來(lái)了解一下著色器獲取數(shù)據(jù)的四種方式:
            • 屬性和緩沖:緩沖是發(fā)送到 GPU 的一些二進(jìn)制數(shù)據(jù)序列,通常情況下緩沖數(shù)據(jù)包括位置、方向、紋理坐標(biāo)、頂點(diǎn)顏色值等。當(dāng)然你可以根據(jù)自己的需要存儲(chǔ)任何你想要的數(shù)據(jù)。屬性用于說(shuō)明如何從緩沖中獲取所需數(shù)據(jù)并將它提供給頂點(diǎn)著色器。
            • 全局變量:全局變量在著色程序運(yùn)行前賦值,在運(yùn)行過(guò)程中全局有效。全局變量在一次繪制過(guò)程中傳遞給著色器的值都一樣。
            • 紋理:紋理是一個(gè)數(shù)據(jù)序列,可以在著色程序運(yùn)行中隨意讀取其中的數(shù)據(jù)。一般情況下我們?cè)诩y理中存儲(chǔ)的大都是圖像數(shù)據(jù),但你也可以根據(jù)自己喜歡存放除了顏色數(shù)據(jù)以外的其它數(shù)據(jù)
            • 可變量:可變量是一種頂點(diǎn)著色器給片元著色器傳值的方式

          小結(jié)

          WebGL 只關(guān)心兩件事:裁剪空間中的坐標(biāo)值和顏色值。使用 WebGL 只需要給它提供這兩個(gè)東西。因此我們通過(guò)提供兩個(gè)著色器來(lái)做這兩件事,一個(gè)頂點(diǎn)著色器提供裁剪空間坐標(biāo)值,一個(gè)片元著色器提供顏色值。

          WebGL 工作原理

          了解完 WebGL 的一些基本概念,我們可以一起來(lái)看看 WebGL 在 GPU 上的工作都做了些什么。正如我們之前了解到的 WebGL 在 GPU 上的工作主要分為兩個(gè)部分,即頂點(diǎn)著色器所做的工作(將頂點(diǎn)轉(zhuǎn)換為裁剪空間坐標(biāo))和片元著色器所做的工作(基于頂點(diǎn)著色器的計(jì)算結(jié)果繪制像素點(diǎn))。假如我們需要繪制一個(gè)三角形,此時(shí) GPU 上進(jìn)行的工作便是先調(diào)用三次頂點(diǎn)著色器計(jì)算出三角形的 3 個(gè)頂點(diǎn)在裁剪空間坐標(biāo)系中的對(duì)應(yīng)位置,并通過(guò)變量 gl_Position 保存在 GPU 中,然后調(diào)用片元著色器完成每個(gè)頂點(diǎn)顏色值的計(jì)算,并通過(guò)變量 gl_FragColor 將對(duì)應(yīng)的顏色值存儲(chǔ)在 GPU 中。完成這些工作后我們已經(jīng)得到了繪制三角形所需的像素點(diǎn),最后便是光柵化三角形了。

          原生 WebGL API 繪制三角形

          前面我們已經(jīng)學(xué)習(xí)了 WebGL 的發(fā)展史、基本概念和工作原理等內(nèi)容,接下來(lái)我們就該實(shí)踐出真知了,所以我們來(lái)看看如何通過(guò) WebGL 在網(wǎng)頁(yè)中繪制一個(gè)簡(jiǎn)單的三角形。我們知道 WebGL 作為一種 3D 繪圖技術(shù)本身就是依托于 HTML5 中的 canvas 元素而存在的,所以在正式開(kāi)始繪制之前我們需要進(jìn)行一系列的準(zhǔn)備工作:

          • 首先我們需要?jiǎng)?chuàng)建一個(gè) canvas 元素作為繪制三角形所需的畫(huà)布,并完成瀏覽器對(duì) canvas 元素兼容性的測(cè)試。

            function webglInit ({
              const canvasEl = document.createElement('canvas'); // canvas 元素創(chuàng)建
              canvasEl.width = document.body.clientWidth; // 設(shè)置 canvas 畫(huà)布的寬度
              canvasEl.height = document.body.clientHeight; // 設(shè)置 canvas 畫(huà)布的高度
              document.body.append(canvasEl); // 將創(chuàng)建好的 canvas 畫(huà)布添加至頁(yè)面中的 body 元素下
              // 接下來(lái)我們需要判斷瀏覽器對(duì)于 WebGL 的兼容性,如果瀏覽器不支持 WebGL 那么我們就不需要再進(jìn)行下去了
              if(!canvasEl.getContext("webgl") && !canvasEl.getContext("experimental-webgl ")) {
                alert("Your Browser Doesn't Support WebGL");
                return;
              }
              // 如果瀏覽器支持 WebGL,那么我們就獲取 WebGL 的上下文對(duì)象并復(fù)制給變量 gl
              const context = (canvasEl.getContext("webgl"))
              ? canvasEl.getContext("webgl"
              : getContext("experimental-webgl");
              /* 
                設(shè)置視口 context.viewport(x, y, width, height);
                x: 用來(lái)設(shè)定視口的左下角水平坐標(biāo)。默認(rèn)值:0
                y: 用來(lái)設(shè)定視口的左下角垂直坐標(biāo)。默認(rèn)值:0
                width: 用來(lái)設(shè)定視口的寬度。默認(rèn)值:canvas 的寬度
                height: 用來(lái)設(shè)定視口的高度。默認(rèn)值:canvas 的高度
                當(dāng)你第一次創(chuàng)建 WebGL 上下文的時(shí)候,視口的大小和 canvas 的大小是匹配的。然而,如果你重新改變了canvas的大小,你需要告訴 WebGL 上下文設(shè)定新的視口,因此這里作為初次創(chuàng)建這行代碼可以省略
              */

              context.viewport(00, context.canvas.width, context.canvas.height);
              return context;
            }
          • 準(zhǔn)備好了 canvas 畫(huà)布下一步就可以開(kāi)始畫(huà)三角形了,正如我們平常畫(huà)畫(huà)一般,我們需要準(zhǔn)備畫(huà)三角形所需的頂點(diǎn)即頂點(diǎn)著色器,以及三角形對(duì)應(yīng)的填充色即片元著色器

            const gl =  webglInit();
            // 創(chuàng)建頂點(diǎn)著色器 語(yǔ)法 gl.createShader(type) 此處 type 為枚舉型值為 gl.VERTEX_SHADER 或 gl.FRAGMENT_SHADER 兩者中的一個(gè)
            const vShader = gl.createShader(gl.VERTEX_SHADER) 
            // 編寫(xiě)頂點(diǎn)著色器的 GLSL 代碼 語(yǔ)法 gl.shaderSource(shader, source); shader - 用于設(shè)置程序代碼的 webglShader(著色器對(duì)象) source - 包含 GLSL 程序代碼的字符串
            gl.shaderSource(vShader, `
              attribute vec4 v_position;

              void main() {
                gl_Position = v_position; // 設(shè)置頂點(diǎn)位置
              }
            `
            )
            gl.compileShader(vShader) // 編譯著色器代碼

            const fShader = gl.createShader(gl.FRAGMENT_SHADER) 
            gl.shaderSource(fShader, `
              precision mediump float;
              uniform vec4 f_color;
              void main() {
                gl_FragColor = f_color; // 設(shè)置片元顏色
              }
            `
            // 編寫(xiě)片元著色器代碼 
            gl.compileShader(fShader) // 編譯著色器代碼
          • 前面我們已經(jīng)完成了頂點(diǎn)著色器和片元著色器的配置,做好了一切繪制前的準(zhǔn)備工作接下來(lái),接下來(lái)我們就需要?jiǎng)?chuàng)建一個(gè)程序用來(lái)連接我們的頂點(diǎn)著色器和片元著色器完成最終的三角形繪制工作。

            // 創(chuàng)建一個(gè)程序用于連接頂點(diǎn)著色器和片元著色器
            const program = gl.createProgram() 
            gl.attachShader(program, vShader) // 添加頂點(diǎn)著色器
            gl.attachShader(program, fShader) // 添加片元著色器
            gl.linkProgram(program) // 連接 program 中的著色器

            gl.useProgram(program) // 告訴 WebGL 用這個(gè) program 進(jìn)行渲染

            const color = gl.getUniformLocation(program, 'f_color'
            // 獲取 f_color 變量位置
            gl.uniform4f(color, 0.9300.561// 設(shè)置它的值

            const position = gl.getAttribLocation(program, 'v_position'
            // 獲取 v_position 位置
            const pBuffer = gl.createBuffer() 
            // 創(chuàng)建一個(gè)頂點(diǎn)緩沖對(duì)象,返回其 id,用來(lái)放三角形頂點(diǎn)數(shù)據(jù),
            gl.bindBuffer(gl.ARRAY_BUFFER, pBuffer) 
            // 將這個(gè)頂點(diǎn)緩沖對(duì)象綁定到 gl.ARRAY_BUFFER
            // 后續(xù)對(duì) gl.ARRAY_BUFFER 的操作都會(huì)映射到這個(gè)緩存
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
                00.5,
                0.50,
                -0.5-0.5
            ]),  // 三角形的三個(gè)頂點(diǎn)
                 // 因?yàn)闀?huì)將數(shù)據(jù)發(fā)送到 GPU,為了省去數(shù)據(jù)解析,這里使用 Float32Array 直接傳送數(shù)據(jù)
            gl.STATIC_DRAW // 表示緩沖區(qū)的內(nèi)容不會(huì)經(jīng)常更改
            )
            // 將頂點(diǎn)數(shù)據(jù)加入的剛剛創(chuàng)建的緩存對(duì)象

            gl.vertexAttribPointer( // 告訴 OpenGL 如何從 Buffer 中獲取數(shù)據(jù)
                position, // 頂點(diǎn)屬性的索引
                2// 組成數(shù)量,必須是 1,2,3 或 4。我們只提供了 x 和 y
                gl.FLOAT, // 每個(gè)元素的數(shù)據(jù)類(lèi)型
                false// 是否歸一化到特定的范圍,對(duì) FLOAT 類(lèi)型數(shù)據(jù)設(shè)置無(wú)效
                0// stride 步長(zhǎng) 數(shù)組中一行長(zhǎng)度,0 表示數(shù)據(jù)是緊密的沒(méi)有空隙,讓 OpenGL 決定具體步長(zhǎng)
                0 // offset 字節(jié)偏移量,必須是類(lèi)型的字節(jié)長(zhǎng)度的倍數(shù)。
            )
            gl.enableVertexAttribArray(position);
            // 開(kāi)啟 attribute 變量額,使頂點(diǎn)著色器能夠訪(fǎng)問(wèn)緩沖區(qū)數(shù)據(jù)

            gl.clearColor(0111// 設(shè)置清空顏色緩沖時(shí)的顏色值
            gl.clear(gl.COLOR_BUFFER_BIT) // 清空顏色緩沖區(qū),也就是清空畫(huà)布
            // 語(yǔ)法 gl.drawArrays(mode, first, count); mode - 指定繪制圖元的方式 first - 指定從哪個(gè)點(diǎn)開(kāi)始繪制 count - 指定繪制需要使用到多少個(gè)點(diǎn)
            gl.drawArrays( gl.TRIANGLES, 03 )

          配合 HTML 文件運(yùn)行上述代碼后我們可以在網(wǎng)頁(yè)中看到如圖所示的三角形,且三角形大小根據(jù)瀏覽器窗口大小自適應(yīng)。可以看到僅僅是繪制一個(gè)簡(jiǎn)單的三角形我們就已經(jīng)寫(xiě)了一大長(zhǎng)串的 JS 代碼,如果真的用原生 WebGL  API 編寫(xiě)一個(gè)動(dòng)態(tài)的 3D 交互式網(wǎng)頁(yè),那么開(kāi)發(fā)成本可見(jiàn)是極其昂貴的。

          WebGL 原生 API 開(kāi)發(fā)的不足

          上面原生 WebGL API 繪制三角形的例子,充分向我們展示了使用原生 WebGL API 開(kāi)發(fā) 3D 交互式網(wǎng)頁(yè)存在的問(wèn)題。盡管從功能上而言原生 WebGL API 可以滿(mǎn)足我們?nèi)我鈭?chǎng)景的開(kāi)發(fā)需要但是,其開(kāi)發(fā)和學(xué)習(xí)的成本極其昂貴。對(duì)于 WebGL 的初學(xué)者而言是極度不友好的,我們需要配置頂點(diǎn)著色器用于計(jì)算繪制頂點(diǎn)所在的位置,而這對(duì)于開(kāi)發(fā)者而言需要一定的數(shù)學(xué)基礎(chǔ)熟悉矩陣的運(yùn)算,同時(shí)也要有空間幾何的概念熟悉 3D 物體的空間分布。而場(chǎng)景的光照,紋理等的設(shè)計(jì)也都需要對(duì)顏色的配置有自己的見(jiàn)解。所以為了給初學(xué)者降低難度,下面我將介紹一些 WebGL 開(kāi)發(fā)的常用框架。

          幾種 WebGL 開(kāi)發(fā)的框架

          • Three.js
            • Three.js 是 WebGL 的綜合庫(kù),其應(yīng)用范圍比較廣泛,美中不足的一點(diǎn)是,Three.js 庫(kù)沒(méi)有比較全面詳細(xì)的官方文檔,對(duì)于使用者而言不是特別友好
          • Cesium.js
            • Cesium.js 是專(zhuān)用于 3D 地圖開(kāi)發(fā)的 WebGL 庫(kù),其擁有較為全面的 3D 地圖開(kāi)發(fā) API,對(duì)于需要開(kāi)發(fā) 3D 地圖的開(kāi)發(fā)者而言是一個(gè)不錯(cuò)的選擇,但針對(duì)其他場(chǎng)景的應(yīng)用開(kāi)發(fā)覆蓋的就不是很全面了
          • Babylon.js
            • Babylon.js 是一款國(guó)外應(yīng)用較廣泛的 WebGL 庫(kù),感興趣的小伙伴可以自己去了解一下,這里就不做詳細(xì)介紹了

          Three.js 是一款運(yùn)行在瀏覽器中的 3D 引擎,你可以用它創(chuàng)建各種三維場(chǎng)景,同時(shí) Three.js 也是一個(gè)綜合性的 WebGL 庫(kù)。如果你需要進(jìn)行 3D 地圖網(wǎng)頁(yè)的開(kāi)發(fā)那就可以用到 Cesium.js 了,Cesium.js 是一款專(zhuān)用于地圖開(kāi)發(fā)的 WebGL 庫(kù)。而 Babylon.js 則是國(guó)外較火的 WebGL 庫(kù)。

          基于 Three.js 繪制旋轉(zhuǎn)立方體

          • 運(yùn)用 Three.js 繪制旋轉(zhuǎn)立方體的第一步同原生 WebGl 一樣,首先便是要準(zhǔn)備 Three.js 運(yùn)行所需的環(huán)境。

            // 創(chuàng)建 renderer 變量用于存儲(chǔ)渲染器對(duì)象
            var renderer;
            // initThree 函數(shù)用來(lái)初始化 Three.js 運(yùn)行所需的環(huán)境
            function initThree({
              // 同原生 WebGL 環(huán)境搭建過(guò)程一樣,Three.js 也需要先設(shè)置畫(huà)布 canvas 元素的大小
              width = document.getElementById('canvas-frame').clientWidth; // 設(shè)置寬度屬性為瀏覽器窗口寬度
              height = document.getElementById('canvas-frame').clientHeight; // 設(shè)置高度屬性為瀏覽器窗口高度
              // 新建一個(gè) WebGL 渲染器并賦值給 renderer 變量
              renderer = new THREE.WebGLRenderer({
                antialiastrue
              });
              // 設(shè)置畫(huà)布大小為瀏覽器窗口大小
              renderer.setSize(width, height);
              // 將畫(huà)布元素掛載到頁(yè)面
              document.getElementById('canvas-frame').appendChild(renderer.domElement);
              // 設(shè)置清空畫(huà)布的顏色為白色
              renderer.setClearColor(0xFFFFFF1.0);
            }
          • 接下來(lái)不同于原生 WebGL 需要準(zhǔn)備頂點(diǎn)著色器和片元著色器,Three.js 需要準(zhǔn)備的是相機(jī)。Three.js 繪制 3D 網(wǎng)頁(yè)所需的 3 大基本要素便是 相機(jī)、場(chǎng)景和物體,當(dāng)然如果有需要設(shè)置明暗效果我們還需要加入第 4 要素光源,光源并不一定需要設(shè)置,但是相機(jī)、場(chǎng)景和物體是一定有的。

            // 創(chuàng)建 camera 變量用于存儲(chǔ)相機(jī)對(duì)象
            var camera;
            // 初始化相機(jī)函數(shù) Three.js 中相機(jī)的類(lèi)型有好幾種可以根據(jù)具體需要進(jìn)行選擇這里我們要?jiǎng)?chuàng)建的是一個(gè)旋轉(zhuǎn)的立方體所以采用的是透視相機(jī),而如果需要?jiǎng)?chuàng)建 3D 陰影效果的場(chǎng)景則需要使用正交相機(jī)
            function initCamera({
              /* 
                創(chuàng)建透一個(gè)視相機(jī)的實(shí)例語(yǔ)法 PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number ) 
                fov - 視角
                aspect - 物體的長(zhǎng)寬比
                near - 相機(jī)近點(diǎn)截圖
                far - 相機(jī)遠(yuǎn)點(diǎn)截圖
              */

              camera = new THREE.PerspectiveCamera(45, width / height, 110000);
              camera.position.x = 0// 設(shè)置相機(jī)在三維空間坐標(biāo)中 x 軸的位置
              camera.position.y = 10// 設(shè)置相機(jī)在三維空間坐標(biāo)中 y 軸的位置
              camera.position.z = 5// 設(shè)置相機(jī)在三維空間坐標(biāo)中 z 軸的位置
              camera.up.x = 0;
              camera.up.y = 0;
              camera.up.z = 1;
              camera.lookAt(new THREE.Vector3(0,0,0));// 設(shè)置相機(jī)的觀(guān)察點(diǎn)
            }
          • 上一步我們完成了相機(jī)的設(shè)置,下面我們來(lái)準(zhǔn)備 Three.js 繪制 3D 網(wǎng)頁(yè)所需的第二要素場(chǎng)景。

            // 創(chuàng)建 scene 變量用于存儲(chǔ)場(chǎng)景對(duì)象
            var scene;
            // initScene 函數(shù)創(chuàng)建一個(gè)場(chǎng)景并賦值給 scene 變量
            function initScene({
              scene = new THREE.Scene();
            }
          • 準(zhǔn)備好了相機(jī)和場(chǎng)景下面我們就需要設(shè)置拍攝的物體了,完成物體的繪制后將其添加到場(chǎng)景中。

            // 創(chuàng)建一個(gè) cube 變量用于存放幾何立方體
            var cube;

            // initObject 函數(shù)就是我們創(chuàng)建場(chǎng)景的核心了
            function initObject({
              // 首先創(chuàng)建一個(gè)一個(gè)幾何類(lèi)的實(shí)例并賦值給 geometry 變量
              var geometry = new THREE.BoxGeometry(111); 
              // 然后創(chuàng)建一種材質(zhì)的實(shí)例 MeshBasicMaterial 材質(zhì)的構(gòu)造函數(shù)能夠創(chuàng)建一種簡(jiǎn)單的不受場(chǎng)景燈光效果影響的材質(zhì)
              var material = new THREE.MeshBasicMaterial( { color0x00ff00 } );
              // Mesh 是一種三角形網(wǎng)格基本單元的構(gòu)造函數(shù),類(lèi)似于我們?cè)?nbsp;WebGL 中的片元著色器它用于連接幾何體和材質(zhì)
              cube = new THREE.Mesh( geometry, material );
              // 最后將創(chuàng)建好的幾何立方體添加到場(chǎng)景中
              scene.add(cube);
            }
          • 到這里我們已經(jīng)完成了 Three.js 繪制 3D 網(wǎng)頁(yè)所需的基本配置,當(dāng)然如果有需要對(duì) 3D 網(wǎng)頁(yè)的明暗效果,燈光顏色做處理的我們還可以在場(chǎng)景中加入燈光的配置,這里由于我們的旋轉(zhuǎn)立方體對(duì)于燈光并未有什么特殊的要求,所以我們便直接進(jìn)入最后一步場(chǎng)景的渲染。

            // render 函數(shù)提供了瀏覽器的循環(huán)渲染功能
            function render({
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;
            renderer.render(scene, camera);
            requestAnimationFrame(render);
            }
            // 最后將 Threee.js 環(huán)境初始化,場(chǎng)景創(chuàng)建,相機(jī)創(chuàng)建渲染器創(chuàng)建以及渲染初始化等函數(shù)合成到一起執(zhí)行我們就完成了一個(gè)旋轉(zhuǎn)立方體的繪制
            function threeStart({
            initThree();
            initCamera();
            initScene();
            initObject();
            render();
            }
            document.addEventListener('DOMContentLoaded',function(){
              threeStart();
            });
          • Three.js 的旋轉(zhuǎn)立方體的繪制還需要配合 HTML 文件使用才能看到效果

            <!DOCTYPE html>
            <html lang="en">
            <head>
              <meta charset="UTF-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Document</title>
              <script type="text/javascript" src="../utils/three.js"></script>
              <style type="text/css">
                div#canvas-frame {
                  border: none;
                  cursor: pointer;
                  width100%;
                  height600px;
                  background-color#EEEEEE;
                }
              
            </style>
            </head>
            <body>
              <div id="canvas-frame"></div>
            </body>
            </html>

            配合 HTML 文件運(yùn)行上述代碼后我們可以在網(wǎng)頁(yè)中看到,一個(gè)旋轉(zhuǎn)的綠色立方體

          小結(jié)

          通過(guò)對(duì)比我們發(fā)現(xiàn)盡管我們通過(guò) Three.js 創(chuàng)建了更為復(fù)雜的場(chǎng)景,但是代碼量相對(duì) WebGL 原生 API 繪制三角形時(shí)反而要少了。由此可見(jiàn)對(duì)于初學(xué)者而言,直接使用 WebGL 原生 API 進(jìn)行 3D 網(wǎng)頁(yè)的開(kāi)發(fā),顯然是不合適的。這時(shí)候我們就可以借助像 Three.js 這樣的 WebGL 封裝庫(kù)進(jìn)行開(kāi)發(fā)。相較之原生 API 的開(kāi)發(fā),這類(lèi)第三方封裝好的 WebGL 庫(kù)大大降低了我們的開(kāi)發(fā)成本,同時(shí)也能幫助我們開(kāi)發(fā)出更加炫酷的頁(yè)面效果。當(dāng)然也不是說(shuō)原生 API 不好,畢竟如果有能力學(xué)透 WebGL 原生 API 的開(kāi)發(fā)還是能夠幫助我們?cè)陂_(kāi)發(fā) 3D 網(wǎng)頁(yè)的時(shí)候?qū)崿F(xiàn)更加隨心所欲的功能,且 Three.js 本身的文檔并不是特別完善所以想要順利的使用同樣需要摸透 WebGL 原生 API。

          總結(jié)

          WebGL 技術(shù)出現(xiàn)的時(shí)間并不算短,然而盡管能夠開(kāi)發(fā)出擁有炫酷效果的 3D 網(wǎng)頁(yè)卻一直未能大火,現(xiàn)今應(yīng)用的最多的也不過(guò)是 3D 網(wǎng)頁(yè)游戲的開(kāi)發(fā)。這其中很大一部分的原因便是受到網(wǎng)速發(fā)展的制約,在當(dāng)今這個(gè)快節(jié)奏的社會(huì)中人們對(duì)于網(wǎng)頁(yè)加載速度的忍耐度是極低的,一個(gè) WebGL 開(kāi)發(fā)的 3D 網(wǎng)頁(yè)動(dòng)輒需要三四秒的打開(kāi)時(shí)間對(duì)用戶(hù)而言無(wú)疑是極度不友好的。但是相信隨著 5G 通信技術(shù)的發(fā)展,網(wǎng)絡(luò)通信技術(shù)飛速發(fā)展下,WebGL 技術(shù)的明天可能會(huì)迎來(lái)新的發(fā)展契機(jī)。

          看完兩件事

          如果你覺(jué)得這篇內(nèi)容對(duì)你挺有啟發(fā),我想邀請(qǐng)你幫我兩件小事

          1.點(diǎn)個(gè)「在看」,讓更多人也能看到這篇內(nèi)容(點(diǎn)了在看」,bug -1 ??

          2.關(guān)注公眾號(hào)「前端圖形學(xué)」,持續(xù)為你推送精選好文
          瀏覽 153
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产又黄又嫩又滑又白 | 99国产毛片 | 91九色丨国产丨爆乳 | 日视频啪啪啪在线观看 | 亚洲日本在线观看视频 |