WebGL 基础入门
什么是 WebGL
WebGL 是一种 3D 绘图协议,衍生于 OpenGL ES2.0,可以结合 Html5 和 JS 在网页上绘制二维或三维的图形。浏览器可以直接运行 WebGL 程序,使用比较简单
实现的功能:
框架:
- Three.js:JS 3D webgl 库
- Babylon.js: web3D 图形引擎
- kickjs;Web 的开源图形引擎和游戏引擎
- ClayGL:构建可扩展的 Web3D 应用程序
- PlayCanvas:网络游戏和 3D 图形引擎
- Luma:Uber 的 3D WebGL 可视化库
- A-Frame:用于构建 VR 体验的 Web 框架
使用 WebGL
创建 Canvas 程序
canvas
import { useEffect } from "react";
function App() {
useEffect(() => {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 100, 100);
}, [])
return <canvas id="canvas" width="400" height="200"></canvas>
}
export default App;预览
创建 WebGL 程序
import { useEffect } from "react";
function App() {
useEffect(() => {
const canvas = document.querySelector("#glcanvas");
// 初始化 WebGL 上下文
const gl = canvas.getContext("webgl");
// 确认 WebGL 支持性
if (!gl) {
alert("无法初始化 WebGL,你的浏览器、操作系统或硬件等可能不支持 WebGL。");
return;
}
// 使用完全不透明的黑色清除所有图像
gl.clearColor(1.0, 0.0, 0.0, 1.0);
// 用上面指定的颜色清除缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
}, []);
return <canvas id="glcanvas" width="100" height="100"></canvas>
}
export default App;预览
绘制一个点
绘制流程如下

import { useEffect } from "react";
function App() {
useEffect(() => {
const canvas = document.querySelector("#glcanvas");
// 初始化 WebGL 上下文
const gl = canvas.getContext("webgl");
// 1. 定义着色器代码
// 顶点着色器代码
const vertexShaderSource = `
void main() {
// 定义坐标 x y z w,结果等于 x/w y/w z/w
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
// 定义顶点大小
gl_PointSize = 30.0;
}
`;
// 片元着色器代码
const fragmentShaderSource = `
void main() {
// 定义颜色值
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
// 2. 创建着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
// 3. 关联着色器与源码
gl.shaderSource(vertexShader, vertexShaderSource);
gl.shaderSource(fragmentShader, fragmentShaderSource);
// 4. 编译着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
// 5. 创建程序对象
const program = gl.createProgram();
// 6. 关联着色器与程序对象
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 7. 使用程序对象
gl.useProgram(program);
// 8. 绘制图行
gl.drawArrays(gl.POINTS, 0, 1);
}, []);
return <canvas id="glcanvas" width="200" height="200" style={{ backgroundColor: "#666" }}></canvas>
}
export default App;预览
可以将初始化着色器相关代码抽离出来
function initShader(gl, vertexShaderSource, fragmentShaderSource) {
// 创建着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
// 关联着色器与源码
gl.shaderSource(vertexShader, vertexShaderSource);
gl.shaderSource(fragmentShader, fragmentShaderSource);
// 编译着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
// 创建程序对象
const program = gl.createProgram();
// 关联着色器与程序对象
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 使用程序对象
gl.useProgram(program);
return program;
}