JavaScript WebGL 3D图形编程实战

首先搭建webgl环境,创建canvas并获取上下文,检查支持性后设置背景色;接着编写GLSL顶点和片元着色器,编译链接成程序;然后定义立方体顶点与索引数据,创建缓冲区上传GPU;启用深度测试,在render中设置投影与视图矩阵,绑定属性并绘制;最后通过requestAnimationFrame实现旋转动画,监听用户交互,完成可交互3D场景。

JavaScript WebGL 3D图形编程实战

WebGL 让你在浏览器中直接运行高性能 3D 图形,无需插件。它基于 OpenGL ES,通过 javaScript 调用 GPU 进行图形渲染。如果你已经掌握 htmljavascript 基础,现在想动手实现一个真实的 3D 场景,这篇文章会带你从零开始,完成一次完整的 WebGL 3D 编程实战。

搭建 WebGL 渲染环境

第一步是准备一个可以绘制 3D 内容的画布(canvas)。

  • 在 HTML 中插入一个 <canvas> 元素,并设置宽高。
  • 使用 JavaScript 获取 canvas 上下文,启用 WebGL 渲染器。
  • 检查浏览器是否支持 WebGL,避免运行时报错。

示例代码:

<font color="#0000FF"><canvas id="glCanvas" width="800" height="600"></canvas></font><script>   const canvas = document.getElementById('glCanvas');   const gl = canvas.getContext('webgl'); <p>if (!gl) { alert('浏览器不支持 WebGL'); }</p><p>gl.clearColor(0.1, 0.1, 0.2, 1.0); // 深蓝背景 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);</p></script>

编写着色器程序

WebGL 使用 GLSL(OpenGL 着色语言)定义顶点和片元着色器。每个 3D 绘制流程都必须包含这两个核心组件。

立即进入豆包AI人工智官网入口”;

立即学习豆包AI人工智能在线问答入口”;

  • 顶点着色器:处理每个顶点的位置变换。
  • 片元着色器:决定像素的颜色(光照、纹理等)。
  • 将 GLSL 代码写入 script 标签或字符串中,编译并链接成着色程序。

示例着色器:

 // 顶点着色器 const vsSource = `   attribute vec4 aVertexPosition;   uniform mat4 uModelViewMatrix;   uniform mat4 uProjectionMatrix;   void main() {     gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;   } `; <p>// 片元着色器 const fsSource = <code> void main() { gl_FragColor = vec4(1.0, 0.8, 0.4, 1.0); // 橙色 } </code>;</p>

编译与链接:

 function createShader(gl, type, source) {   const shader = gl.createShader(type);   gl.shaderSource(shader, source);   gl.compileShader(shader);   if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {     console.error('Shader 编译失败:', gl.getShaderInfoLog(shader));     gl.deleteShader(shader);     return null;   }   return shader; } <p>function createProgram(gl, vsSource, fsSource) { const vertexShader = createShader(gl, gl.VERTEX_SHADER, vsSource); const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fsSource); const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.error('Program 链接失败:', gl.getProgramInfoLog(program)); return null; } return program; }</p><p>const shaderProgram = createProgram(gl, vsSource, fsSource);</p>

定义几何数据并绘制立方体

接下来创建一个 3D 立方体。你需要提供顶点坐标,并设置索引以减少重复数据。

JavaScript WebGL 3D图形编程实战

豆包AI编程

豆包推出的AI编程助手

JavaScript WebGL 3D图形编程实战483

查看详情 JavaScript WebGL 3D图形编程实战

  • 定义 8 个顶点位置,构成立方体的角点。
  • 使用 index buffer(元素数组缓冲)指定如何连接顶点形成三角形。
  • 启用深度测试,防止远处物体覆盖近处物体。

示例:创建立方体顶点与索引

 const positions = [   -1, -1,  1,    1, -1,  1,    1,  1,  1,   -1,  1,  1,   -1, -1, -1,    1, -1, -1,    1,  1, -1,   -1,  1, -1, ]; <p>const indices = [ 0, 1, 2,    0, 2, 3,  // 前面 4, 5, 6,    4, 6, 7,  // 后面 1, 5, 6,    1, 6, 2,  // 右侧 // 更多面... ];</p><p>// 创建缓冲区 const positionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);</p><p>const indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);</p><p>// 启用深度测试 gl.enable(gl.DEPTH_TEST);</p>

在 render 函数中绘制:

 function render() {   gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); <p>const projectionMatrix = mat4.perspective( mat4.create(),  45 * Math.PI / 180,  canvas.width / canvas.height,  0.1, 100.0 );</p><p>const modelViewMatrix = mat4.translate(mat4.create(), [0, 0, -6]);</p><p>// 将矩阵传入着色器 gl.uniformMatrix4fv( gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), false, projectionMatrix ); gl.uniformMatrix4fv( gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), false, modelViewMatrix );</p><p>// 绑定顶点缓冲 gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); const vertexPosition = gl.getAttribLocation(shaderProgram, 'aVertexPosition'); gl.vertexAttribPointer(vertexPosition, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vertexPosition);</p><p>// 绘制元素 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); } render();</p>

添加动画与用户交互

让立方体旋转起来,提升视觉体验。

  • 使用 requestAnimationFrame 实现平滑动画循环
  • 在每一帧更新 modelViewMatrix 的旋转角度。
  • 监听鼠标或键盘事件控制视角或旋转方向。

动画实现:

 let rotation = 0; <p>function animate() { rotation += 0.01; render(rotation); requestAnimationFrame(animate); }</p><p>function render(rot) { // ...清空缓冲</p><p>mat4.translate(modelViewMatrix, [0, 0, -6]); mat4.rotateY(modelViewMatrix, modelViewMatrix, rot); mat4.rotateX(modelViewMatrix, modelViewMatrix, rot * 0.5);</p><p>// 传递矩阵并绘制 // ... } animate();</p>

基本上就这些。你已经完成了从初始化 WebGL 到绘制可动画 3D 立方体的全过程。虽然原生 WebGL API 较为底层,但理解它能帮你更好地使用 Three.js 等高级库。不复杂但容易忽略细节,比如矩阵顺序、缓冲绑定、着色器编译状态检查等,都是实战中的关键点。

上一篇
下一篇
text=ZqhQzanResources