使用 WebGL 創建 3D 對象

WebGL Demoicon-default.png?t=N7T8https://mdn.github.io/dom-examples/webgl-examples/tutorial/sample5/index.html

現在讓我們給之前的正方形添加五個面從而可以創建一個三維的立方體。最簡單的方式就是通過調用方法?gl.drawElements()?使用頂點數組列表來替換之前的通過方法gl.drawArrays()?直接使用頂點數組。而頂點數組列表里保存著將會被引用到一個個獨立的頂點。

其實現在會存在這樣一個問題:每個面需要 4 個頂點,而每個頂點會被 3 個面共享。我們會創建一個包含 24 個頂點的數組列表,通過使用數組下標來索引頂點,然后把這些用于索引的下標傳遞給渲染程序而不是直接把整個頂點數據傳遞過去,這樣來減少數據傳遞。那么也許你就會問:那么使用 8 個頂點就好了,為什么要使用 24 個頂點呢?這是因為每個頂點雖然被 3 個面共享但是它在每個面上需要使用不同的顏色信息。24 個頂點中的每一個都會有獨立的顏色信息,這就會造成每個頂點位置都會有 3 份副本。

定義立方體頂點位置

首先,更新?initBuffers()?函數中代碼來創建立方體的頂點位置緩存區。現在的代碼看起來和渲染正方形時的代碼很相似,只是比之前的代碼更長因為現在有了 24 個頂點(每個面使用 4 個頂點):

備注:?在“init-buffers.js”文件?initPositionBuffer()?函數中,用下面代碼替換?positions

JSCopy to Clipboard

const positions = [// Front face-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,// Back face-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0,// Top face-1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,// Bottom face-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,// Right face1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,// Left face-1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0,
];

由于我們給頂點添加了 Z 分量,因此我們需要將?vertexPosition?屬性的?numComponents?更新為 3。

備注:?在“draw-scene.js”文件?setPositionAttribute()?函數中,將?numComponents?從?2?改為?3:

JSCopy to Clipboard

const numComponents = 3;

定義頂點顏色

然后我們還要為每個頂點定義顏色。下面的代碼首先為每個面定義顏色,然后用一個循環語句為每個頂點定義顏色信息。

備注:?在“init-buffers.js”文件?initColorBuffer()?函數中,用下面代碼替換?colors?定義:

JSCopy to Clipboard

const faceColors = [[1.0, 1.0, 1.0, 1.0], // Front face: white[1.0, 0.0, 0.0, 1.0], // Back face: red[0.0, 1.0, 0.0, 1.0], // Top face: green[0.0, 0.0, 1.0, 1.0], // Bottom face: blue[1.0, 1.0, 0.0, 1.0], // Right face: yellow[1.0, 0.0, 1.0, 1.0], // Left face: purple
];// Convert the array of colors into a table for all the vertices.var colors = [];for (var j = 0; j < faceColors.length; ++j) {const c = faceColors[j];// Repeat each color four times for the four vertices of the facecolors = colors.concat(c, c, c, c);
}

定義元素(三角形)數組

既然已經創建好了頂點數組,接下來就要創建元素(三角形)數組了。

備注:?在“init-buffer.js”文件中添加下面的函數:

JSCopy to Clipboard

function initIndexBuffer(gl) {const indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);// This array defines each face as two triangles, using the// indices into the vertex array to specify each triangle's// position.const indices = [0,1,2,0,2,3, // front4,5,6,4,6,7, // back8,9,10,8,10,11, // top12,13,14,12,14,15, // bottom16,17,18,16,18,19, // right20,21,22,20,22,23, // left];// Now send the element array to GLgl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(indices),gl.STATIC_DRAW,);return indexBuffer;
}

indices?數組聲明每一個面都使用兩個三角形來渲染。通過立方體頂點數組的索引指定每個三角形的頂點。那么這個立方體就是由 12 個三角形組成的了。

備注:?在“init-buffers.js”文件?initBuffers()函數中,添加下面的代碼替換之前的?return?代碼片段:

JSCopy to Clipboard

const indexBuffer = initIndexBuffer(gl);return {position: positionBuffer,color: colorBuffer,indices: indexBuffer,
};

渲染立方體

接下來就需要在?drawScene()?函數里添加代碼使用立方體頂點索引數據來渲染這個立方體了。代碼里添加了對?gl.bindBuffer()?和?gl.drawElements()的調用:

備注:?在?drawScene()?函數中,gl.useProgram?代碼前添加如下代碼:

JSCopy to Clipboard

// Tell WebGL which indices to use to index the vertices
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices);

備注:?在“draw-scene.js”文件?drawScene()?函數中,用下面這段代碼替換之前?gl.drawArrays()

JSCopy to Clipboard

{const vertexCount = 36;const type = gl.UNSIGNED_SHORT;const offset = 0;gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);
}

立方體的每個面都由 2 個三角形組成,那就是每個面需要 6 個頂點,或者說總共 36 個頂點,盡管有許多重復的。然而,因為索引數組的每個元素都是簡單的整數類型,所以每一幀動畫需要傳遞給渲染程序的數據也不是很多。

最后,讓我們把變量?squareRotation?替換成?cubeRotation?并添加 X 軸的第二個旋轉。

備注:?在“webgl-demo.js”文件的頭部,把變量?squareRotation?替換成?cubeRotation

JSCopy to Clipboard

let cubeRotation = 0.0;

備注:?在?drawScene()?函數聲明中,將變量?squareRotation?替換成?cubeRotation

JSCopy to Clipboard

function drawScene(gl, programInfo, buffers, cubeRotation) {

備注:?在?drawScene()?函數中,用下面代碼替換之前的?mat4.rotate?函數:

JSCopy to Clipboard

mat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation, // amount to rotate in radians[0, 0, 1],
); // axis to rotate around (Z)
mat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation * 0.7, // amount to rotate in radians[0, 1, 0],
); // axis to rotate around (Y)
mat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation * 0.3, // amount to rotate in radians[1, 0, 0],
); // axis to rotate around (X)

備注:?在?main()?函數中,替換?drawScene()?函數調用參數中的?squareRotation?為?cubeRotation

JSCopy to Clipboard

drawScene(gl, programInfo, buffers, cubeRotation);
cubeRotation += deltaTime;

到現在為止,我們已經創建了一個顏色生動的并且會在場景中移動和旋轉的立方體,這一定很酷吧。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/36904.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36904.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/36904.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

TinTin Web3 動態精選:Aptos Builder Jam 亞洲首站即將開啟,Solana 實現全網連接

TinTin 快訊由 TinTinLand 開發者技術社區打造&#xff0c;旨在為開發者提供最新的 Web3 新聞、市場時訊和技術更新。TinTin 快訊將以周為單位&#xff0c; 匯集當周內的行業熱點并以快訊的形式排列成文。掌握一手的技術資訊和市場動態&#xff0c;將有助于 TinTinLand 社區的開…

檢測SD NAND文件系統異常和修復的方法

目錄 1、打開命令提示符&#xff1a; 2、運行chkdsk命令&#xff1a; 3、命令參數說明&#xff1a; chkdsk是Windows中的一個命令行工具&#xff0c;用于檢查磁盤上的文件系統錯誤和修復壞塊。MK米客方德為您提供指導&#xff0c;以下是使用chkdsk的步驟&#xff1a; 1、打開…

綜合IT運維管理解決方案

綜合IT運維管理解決方案 在信息化和數字化高速發展的時代&#xff0c;企業的IT運維管理已經成為保障業務連續性和提升運營效率的關鍵環節。高效的IT運維管理不僅能夠降低運維成本&#xff0c;還能提升服務質量和用戶滿意度。本文將詳細介紹綜合IT運維管理解決方案&#xff0c;…

富格林:正規平臺曝光出金招數

富格林悉知&#xff0c;在現貨黃金中&#xff0c;正規盈利出金是要建立在無落入誘導風險的情況下實現的&#xff0c;投資者要關注的不僅僅是如何進行盈利&#xff0c;還要掌握正規平臺曝光的交易技巧或經驗。對于新手投資者來說&#xff0c;學習投資的基礎知識&#xff0c;提升…

eBPF技術揭秘:DeepFlow如何引領故障排查,提升運維效率

DeepFlow 實戰&#xff1a;eBPF 技術如何提升故障排查效率 目錄 DeepFlow 實戰&#xff1a;eBPF 技術如何提升故障排查效率 微服務架構系統中各個服務、組件及其相互關系的全景 零侵擾分布式追蹤&#xff08;Distributed Tracing&#xff09;的架構和工作流程 關于零侵擾持…

華為od 2024 | 什么是華為od,od 薪資待遇,od機試題清單

目錄 專欄導讀華為OD機試算法題太多了&#xff0c;知識點繁雜&#xff0c;如何刷題更有效率呢&#xff1f; 一、邏輯分析二、數據結構1、線性表① 數組② 雙指針 2、map與list3、隊列4、鏈表5、棧6、滑動窗口7、二叉樹8、并查集9、矩陣 三、算法1、基礎算法① 貪心思維② 二分查…

后端系統的安全性

后端系統的安全性 后端系統的安全性是任何Web應用或服務的核心組成部分&#xff0c;它涉及保護數據、用戶隱私以及系統免受惡意攻擊。以下是后端安全的一些關鍵點&#xff1a; 認證和授權&#xff1a;確保只有經過身份驗證的用戶才能訪問特定資源。這通常包括使用用戶名/密碼…

Spring Session將HttpSession保存到Redis中,實現重啟應用會話不丟失

這篇文章介紹一下在springboot項目中整合Spring Session&#xff0c;將session會話信息保存到Redis中&#xff0c;防止重啟應用導致會話丟失。 第一步 創建一個springboot項目&#xff0c;添加spring-session-redis的依賴&#xff0c;因為要用到reids&#xff0c;所以要把redi…

擴散模型中的UNET

目錄 一、為什么UNET模型可以用于去噪網絡二、擴散模型中的UNET是一個條件去噪網絡&#xff0c;怎么實現的三、UNET用于分割和用去去噪的區別 一、為什么UNET模型可以用于去噪網絡 下采樣部分: 能夠提取圖像的深層次特征&#xff0c;這些特征往往包含圖像的重要結構和信息&…

Python 繼承:理解與應用

Python中的繼承是面向對象編程中重要的概念之一&#xff0c;允許一個類&#xff08;子類&#xff09;從另一個類&#xff08;父類&#xff09;繼承屬性和方法。這種機制不僅能提高代碼的重用性&#xff0c;還有助于構建層次化的數據模型&#xff0c;簡化復雜系統的設計與維護。…

原型開發:加速需求驗證與設計優化

目錄 前言1. 原型開發的意義1.1 定義與概述1.2 原型的類型 2. 原型開發的優勢2.1 明確需求2.2 提升用戶滿意度2.3 降低開發風險 3. 原型開發的挑戰3.1 過多的原型開發3.2 資源投入與管理3.3 期望管理 4. 優化原型開發流程4.1 明確目標與范圍4.2 選擇合適的工具和方法4.3 加強用…

【MySQL基礎篇】概述及SQL指令:DDL及DML

數據庫是一個按照數據結構來組織、存儲和管理數據的倉庫。以下是對數據庫概念的詳細解釋&#xff1a;定義與基本概念&#xff1a; 數據庫是長期存儲在計算機內的、有組織的、可共享的、統一管理的大量數據的集合。 數據庫不僅僅是數據的簡單堆積&#xff0c;而是遵循一定的規則…

JS 數組刪除指定元素以及數組排序

刪除 function cut(value) { return value.slice(0,value.length-1) } 排序 let arr [5,2,1,4,9,8] for(let i 0 ; i < arr.length ; i ) { for(let j 0 ; j < arr.length -1 ; j ) { if(arr[j] > arr[j1]){ let num arr[j] arr[j] arr[j1] arr[j1] num come…

C++之STL(十一)

1、迭代器適配器 2、插入迭代器 #include <iostream> #include <vector> #include <algorithm> #include <list> using namespace std;void showVec(const vector<int>& v) {for (vector<int>::const_iterator it v.begin(); it ! v.…

導出word模板開發記錄

exportWordDocx.js import JSZipUtils from “jszip-utils” import Docxtemplater from “docxtemplater” import {saveAs} from “file-saver” import PizZip from “pizzip” const exportWordDocx (demoUrl, docxData, fileName) > {// 讀取并獲得模板文件的二進制…

視頻壓縮怎么壓縮最小,怎么把視頻壓縮的很小

壓縮視頻怎么壓縮到很小&#xff1f;視頻是我們在生活中不可或缺的一部分&#xff0c;隨著制作視頻的小伙伴越來越多&#xff0c;大家都想把制作好的視頻上傳到一些平臺或傳給別人&#xff0c;有時候我們會遇到視頻內存過大的問題&#xff0c;今天我給大家介紹一個快速把視頻壓…

SQLite:一個極簡使用教程

SQLite是一個輕量級的、文件系統基礎的數據庫&#xff0c;它被設計為配置簡單、易于部署。SQLite數據庫存儲在一個單一的磁盤文件中&#xff0c;這意味著數據庫的創建和維護都非常簡單。 1. SQLite特點 輕量級&#xff1a;SQLite不需要一個獨立的服務器進程。它是一個嵌入式SQ…

萬物皆可爬——亮數據代理IP+Python爬蟲批量下載百度圖片助力AI訓練

&#x1f482; 個人網站:【 摸魚游戲】【神級代碼資源網站】【導航大全】&#x1f91f; 一站式輕松構建小程序、Web網站、移動應用&#xff1a;&#x1f449;注冊地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;輕量化工具創作平臺&#x1f485; 想尋找共同學習交…

注意!!2024下《網絡規劃設計師》易混淆知識點來了,趕緊碼住

寶子們&#xff0c;在復習軟考網絡規劃設計師中&#xff0c;是不是覺得有很多知識點含義比較相近&#xff0c;很多友友剛看的時候&#xff0c;估計會像我一樣把它們弄混&#xff0c;作為一個軟考老鳥&#xff0c;在這里給大家整理了網規學習過程中易混淆的知識點&#xff0c;大…

新版彩虹云商城卡密商城/自動發卡可分站多套模板可選

完整免授權彩虹源碼(多模板+小儲云商城模板)版本 6.7.5,部分代碼加密,使用起來一點問題都沒有,加密部分是授權那一塊,可以二開更改一下,就完事 無差錯,免授權,功能齊全,模板齊全。 后臺可設置的模板有 20 套,喜歡的就購買研究學習 支持多個接口,支持到賬到個人錢…