WebGL學習2

WebGL(Web Graphics Library)是一種基于 OpenGL ES 2.0 的 JavaScript API,用于在網頁上實現高性能的 3D 圖形渲染。

1. 初始化 WebGL 上下文

在使用 WebGL 之前,需要獲取<canvas>元素并創建 WebGL 上下文。

// 獲取canvas
const canvas = document.querySelector('canvas');
// 獲取webgl上下文對象,注意選擇webgl的1.0版本,2.0版本有一些語法不一樣
const gl = canvas.getContext('webgl');
  • document.querySelector('canvas'):通過選擇器獲取 HTML 文檔中的<canvas>元素。
  • canvas.getContext('webgl'):獲取<canvas>元素的 WebGL 上下文。如果瀏覽器不支持 WebGL,該方法將返回null

2. 著色器編程

WebGL 使用著色器(Shader)來處理圖形渲染的各個階段。著色器是運行在 GPU 上的小程序,主要分為頂點著色器(Vertex Shader)和片元著色器(Fragment Shader)。

import fragShader from '../shader/2.webgl繪制點/fragShader.glsl';
import vertexShader from '../shader/2.webgl繪制點/vertexShader.glsl';
import { initShader } from '../lib';// fragShader和vertexShader引入之后是字符串,需要被編譯為可執行的程序
const program = initShader(gl, vertexShader, fragShader);
  • 頂點著色器(Vertex Shader):負責處理每個頂點的位置、顏色等屬性。
  • 片元著色器(Fragment Shader):負責處理每個像素的顏色。
  • initShader函數:用于初始化著色器,創建并配置程序對象。
export function initShader(gl, vshader_source, fshader_source) {// 創建著色器const vertexShader = createShaderFromString(gl,gl.VERTEX_SHADER,vshader_source);const fragmentShader = createShaderFromString(gl,gl.FRAGMENT_SHADER,fshader_source);// 創建一個程序對象 操作手,專門負責javaScript和shader著色器的通訊const program = gl.createProgram();gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);// 將javascrpt和程序對象關聯gl.linkProgram(program);// 使用程序對象gl.useProgram(program);// 返回程序對象return program;
}
  • gl.createShader(type):創建一個指定類型的著色器對象(gl.VERTEX_SHADERgl.FRAGMENT_SHADER)。
  • gl.shaderSource(shader, source):將著色器源代碼賦值給著色器對象。
  • gl.compileShader(shader):編譯著色器對象。
  • gl.createProgram():創建一個程序對象,用于管理著色器。
  • gl.attachShader(program, shader):將著色器對象附加到程序對象上。
  • gl.linkProgram(program):鏈接程序對象,將頂點著色器和片元著色器關聯起來。
  • gl.useProgram(program):使用指定的程序對象進行渲染。

3. 緩沖區對象

緩沖區對象(Buffer Object)用于在 CPU 和 GPU 之間傳遞數據,如頂點坐標、顏色等。

// 1.創建頂點數據對象
const vertices = new Float32Array([0, 0.5,-0.5, -0.5,0.5, -0.5,
]);// 2.創建緩沖區對象
const buffer = gl.createBuffer();// 3.綁定緩沖區對象的用途
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);// 4.向緩沖區中寫入數據
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);// 5.設置attribute變量對緩沖區的訪問規則
const a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);// 6.啟動數據讀取
gl.enableVertexAttribArray(a_Position);
  • gl.createBuffer():創建一個緩沖區對象。
  • gl.bindBuffer(target, buffer):將緩沖區對象綁定到指定的目標(gl.ARRAY_BUFFER用于存儲頂點數據)。
  • gl.bufferData(target, data, usage):向緩沖區對象中寫入數據。usage參數指定數據的使用方式,gl.STATIC_DRAW表示數據不會頻繁更改。
  • gl.getAttribLocation(program, name):獲取頂點著色器中attribute變量的位置。
  • gl.vertexAttribPointer(index, size, type, normalized, stride, offset):設置attribute變量對緩沖區的訪問規則。
    • indexattribute變量的位置。
    • size:每個頂點的分量個數。
    • type:數據的類型,如gl.FLOAT
    • normalized:是否需要歸一化。
    • stride:連續頂點屬性之間的間隔。
    • offset:頂點屬性在數組中的偏移量。
  • gl.enableVertexAttribArray(index):啟用指定位置的attribute變量。

4. 繪制圖形

使用gl.drawArraysgl.drawElements方法繪制圖形。

// 最后調用drawArrays繪制,這里可以將count取3,一次繪制三個點
gl.drawArrays(gl.POINTS, 0, 3);
  • gl.drawArrays(mode, first, count):從指定位置開始,繪制指定數量的頂點。
    • mode:繪制模式,如gl.POINTS(點)、gl.LINES(線)、gl.TRIANGLES(三角形)等。
    • first:從第幾個頂點開始繪制。
    • count:要繪制的頂點數量。

5. 深度檢測

深度檢測用于判斷物體的正確遮擋關系。

// 深度檢測,用來判斷物體的正確遮擋關系
gl.enable(gl.DEPTH_TEST);
  • gl.enable(capability):啟用指定的功能,gl.DEPTH_TEST表示啟用深度檢測。

6. 相機和投影矩陣

在 3D 場景中,需要使用相機和投影矩陣來定義視角和投影方式。

import { mat4 } from 'gl-matrix';
import PerspectiveCamera from '../lib/PerspectiveCamera';// viewMatrix的參數
const vModelView = {viewX: 0,viewY: 0,viewZ: 1,lookAtX: 0,lookAtY: 0,lookAtZ: 0,
};const vModelProj = {fov: 45,aspect: 1,near: 0.1,far: 4,
};
const camera = new PerspectiveCamera(gl, program, {fov: vModelProj.fov,aspect: vModelProj.aspect,near: vModelProj.near,far: vModelProj.far,lookAt: [vModelView.lookAtX, vModelView.lookAtY, vModelView.lookAtZ],position: [vModelView.viewX, vModelView.viewY, vModelView.viewZ],up: [0, 1, 0],
});// 創建視圖矩陣
const createViewMatrix = () => {const viewMatrix = mat4.create();// 創建視圖矩陣,三個參數,相機位置,注視的坐標,上方向mat4.lookAt(viewMatrix,[vModelView.viewX, vModelView.viewY, vModelView.viewZ],[vModelView.lookAtX, vModelView.lookAtY, vModelView.lookAtZ],[0, 1, 0]);gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix);
};// 創建投影矩陣
const createProjMatrix = () => {const projMatrix = mat4.create();// 創建正交投影矩陣mat4.perspectiveNO(projMatrix, ...Object.values(vModelProj));gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix);
};
  • PerspectiveCamera:自定義的透視相機類,用于管理相機的屬性和矩陣。
  • mat4.create():創建一個 4x4 的矩陣。
  • mat4.lookAt(out, eye, center, up):創建視圖矩陣,指定相機的位置、注視點和上方向。
  • mat4.perspectiveNO(out, fovy, aspect, near, far):創建透視投影矩陣。
  • gl.uniformMatrix4fv(location, transpose, value):將矩陣數據傳遞給著色器中的uniform變量。

7. 光照效果

在 WebGL 中,可以實現不同類型的光照效果,如環境光、漫反射光和鏡面高光。

import AmbientLight from '../lib/Light/AmbientLight';
import DiffuseLight from '../lib/Light/DiffuseLight';
import SpecularLight from '../lib/Light/SpecularLight';const vModel = {color: 0xffffff,intensity: 1
};
const vModelDiffuse = {color: 0xffffff,intensity: 1
};
const light = new AmbientLight(gl, program, vModel);
const diffuseLight = new DiffuseLight(gl, program, vModelDiffuse);
const specularLight = new SpecularLight(gl, program);
  • AmbientLight:環境光類,用于模擬全局光照效果。
  • DiffuseLight:漫反射光類,用于模擬物體表面的漫反射光照效果。
  • SpecularLight:鏡面高光類,用于模擬物體表面的鏡面反射光照效果。

8. GUI 交互

使用dat.gui庫可以創建簡單的圖形用戶界面,方便調試和交互。

import * as dat from 'dat.gui';const gui = new dat.GUI();
const vModel = {scale: 1,angle: 0,tx: 0,ty: 0
};gui.add(vModel, 'scale', 0.1, 2).step(0.1).name('縮放').onChange(render);
gui.add(vModel, 'angle', 0, 360).step(1).name('旋轉').onChange(render);
gui.add(vModel, 'tx', -1, 1).step(0.1).name('x軸平移').onChange(render);
gui.add(vModel, 'ty', -1, 1).step(0.1).name('y軸平移').onChange(render);
  • dat.GUI():創建一個 GUI 對象。
  • gui.add(object, property, min, max, step):添加一個滑塊控件,用于控制對象的屬性。
  • onChange(callback):當控件的值發生變化時,調用回調函數。

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

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

相關文章

零知識證明:區塊鏈隱私保護的變革力量

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;…

【java】集合的基本使用

集合是 Java 中用來存儲一組對象的容器。與數組相比&#xff0c;集合更加靈活和強大&#xff0c;支持動態增刪元素、自動擴容、多種數據結構等特性。下面我會用通俗易懂的語言解釋集合的基本使用。 1. 什么是集合&#xff1f; 集合就像是一個“容器”&#xff0c;可以用來裝很多…

WPF-實現按鈕的動態變化

MVVM 模式基礎 視圖模型&#xff08;ViewModel&#xff09;&#xff1a;MainViewModel類作為視圖模型&#xff0c;封裝了與視圖相關的屬性和命令。它實現了INotifyPropertyChanged接口&#xff0c;當屬性值發生改變時&#xff0c;通過OnPropertyChanged方法通知視圖進行更新&am…

主流NoSQL數據庫類型及選型分析

在數據庫領域&#xff0c;不同類型的數據庫針對不同場景設計&#xff0c;以下是四類主流NoSQL數據庫的對比分析&#xff1a; 一、核心特性對比 鍵值數據庫&#xff08;Key-Value&#xff09; 數據模型&#xff1a;簡單鍵值對存儲 特點&#xff1a;毫秒級讀寫、高并發、無固定…

西門子PLC

西門子PLC與C#通信全解析&#xff1a;從協議選型到實戰開發 一、西門子PLC通信協議概述 西門子PLC支持多種通信協議&#xff0c;需根據設備型號及項目需求選擇&#xff1a; S7協議 西門子私有協議&#xff0c;適用于S7-200/300/400/1200/1500系列PLC特點&#xff1a;直接訪問…

Visual Studio(VS)的 Release 配置中生成程序數據庫(PDB)文件

最近工作中的一個測試工具在測試多臺設備上使用過程中閃退&#xff0c;存了dump&#xff0c;但因為是release版本&#xff0c;沒有pdb&#xff0c;無法根據dump定位代碼哪塊出了問題&#xff0c;很苦惱&#xff0c;查了下怎么加pdb生成&#xff0c;記錄一下。以下是具體的設置步…

★ Linux ★ 進程(上)

Ciallo&#xff5e;(∠?ω< )⌒☆ ~ 今天&#xff0c;我將和大家一起學習 linux 進程~ ????????????????????????????? 澄嵐主頁&#xff1a;椎名澄嵐-CSDN博客 Linux專欄&#xff1a;https://blog.csdn.net/2302_80328146/category_12815302…

JAVA并發-volatile底層原理

volatile相當于是一個輕量級的synchronized&#xff0c;一般作用在變量上&#xff0c;它具有三個特性&#xff1a;可見性、有序性&#xff0c;相比于synchronized&#xff0c;他的執行成本更低。 先來說可見性&#xff0c;java存在共享變量不可見性的原因就是&#xff0c;線程…

Java面試第十一山!《SpringCloud框架》

大家好&#xff0c;我是陳一。如果文章對你有幫助&#xff0c;請留下一個寶貴的三連哦&#xff5e; 萬分感謝&#xff01; 目錄 一、Spring Cloud 是什么? 二、Spring Cloud 核心組件? 1. 服務發現 - Eureka? 2. ?負載均衡 - Ribbon? 3. 斷路器 - Hystrix? ??4. …

Transaction rolled back because it has been marked as rollback-only問題解決

transaction rolled back because it has been marked as rollback-only 簡略總結> 發生場景&#xff1a;try-catch多業務場景 發生原因&#xff1a;業務嵌套&#xff0c;事務管理混亂&#xff0c;外層業務與內層業務拋出異常節點與回滾節點不一致。 解決方式&#xff1a;修…

sql server數據遷移,springboot搭建開發環境遇到的問題及解決方案

最近搭建springboot項目開發環境&#xff0c;數據庫連的是sql server&#xff0c;遇到許多問題在此記錄一下。 1、sql server安裝教程 參考&#xff1a;https://www.bilibili.com/opus/944736210624970769 2、sql server導出、導入數據庫 參考&#xff1a;https://blog.csd…

【數學建模】灰色關聯分析模型詳解與應用

灰色關聯分析模型詳解與應用 文章目錄 灰色關聯分析模型詳解與應用引言灰色系統理論簡介灰色關聯分析基本原理灰色關聯分析計算步驟1. 確定分析序列2. 數據無量綱化處理3. 計算關聯系數4. 計算關聯度 灰色關聯分析應用實例實例&#xff1a;某企業生產效率影響因素分析 灰色關聯…

Spring配置文件-Bean實例化三種方式

無參構造方法實例化 工廠靜態方法實例化 工廠實例方法實例化

SSL 和 TLS 認證

SSL&#xff08;Secure Sockets Layer&#xff0c;安全套接層&#xff09;認證是一種用于加密網絡通信和驗證服務器身份的安全技術。它是TLS&#xff08;Transport Layer Security&#xff0c;傳輸層安全協議&#xff09;的前身&#xff0c;雖然現在大多數應用使用的是TLS&…

SpringBoot學習(三)SpringBoot整合JSP以及Themeleaf

目錄 Spring Boot 整合 JSP1. 配置依賴2. 創建WEB目錄結構&#xff0c;配置JSP解析路徑3. 創建Controller類4. 修改application.yml5. 添加jstl標簽庫的依賴6. JSP頁面7. 創建啟動類 Spring Boot 整合 Thymeleaf1. 添加Thymeleaf依賴2. Controller3. 修改application.yml配置&a…

普通鼠標的500連擊的工具來了!!!

今天介紹的這款軟件叫&#xff1a;鼠標錄制器&#xff0c;是一款大小只有54K的鼠標連點器&#xff0c;軟件是綠色單文件版。搶票&#xff0c;拍牌&#xff0c;搖號都能用上。文末有分享鏈接 在使用先我們先設置快捷鍵&#xff0c;這樣我們在錄制和停止錄制的時候會更方便。 軟件…

【MySQL】基本查詢(表的增刪查改+聚合函數)

目錄 一、Create1.1 單行數據 全列插入1.2 多行數據 指定列插入1.3 插入否則更新1.4 替換 二、Retrieve2.1 SELECT 列2.1.1 全列查詢2.1.2 指定列查詢2.1.3 查詢字段為表達式2.1.4 為查詢結果指定別名2.1.5 結果去重 2.2 WHERE 條件2.2.1 比較運算符2.2.2 邏輯運算符2.2.3 案…

JAVA中關于圖形化界面的學習(GUI)動作監聽,鼠標監聽,鍵盤監聽

動作監聽&#xff1a; 先創建一個圖形化界面&#xff0c;接著創建一個按鈕對象&#xff0c;設置按鈕的大小。 添加一個addActionListener()&#xff1b; addActionListener() 方法定義在 java.awt.event.ActionListener 接口相關的上下文中&#xff0c;許多支持用戶交互產生…

MySQL 基礎學習文檔

一、MySQL 概述 1.1 核心概念 數據庫 (DB)&#xff1a;存儲數據的結構化倉庫數據庫管理系統 (DBMS)&#xff1a;操作數據庫的軟件&#xff08;如 MySQL、Oracle&#xff09;SQL&#xff1a;操作關系型數據庫的標準語言 1.2 安裝與配置 下載地址&#xff1a;MySQL Installer…

火山引擎(豆包大模型)(抖音平臺)之火山方舟的Prompt的使用測試

前言 在大模型的使用過程當中&#xff0c;Prompt的使用非常的關鍵。原來&#xff0c;我對Prompt的理解不深&#xff0c;覺得Prompt的產生并不是很有必要。但是&#xff0c;自從使用了火山方舟中的“Prompt優解”之后&#xff0c;感受加深了&#xff0c;覺得Prompt是我們和大模型…