You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求WebGL并行性纯GLSL代码的简单完整示例

完整的WebGL并行计算示例(纯GLSL)

嘿,我懂你想要的是不依赖任何抽象库,直接用原生WebGL+GLSL实现并行性的最简完整示例——毕竟看封装好的库永远不如亲手写一遍来得明白。下面这个例子会用GPU并行计算每个像素坐标的平方值,然后把结果渲染成颜色,整个流程清晰易懂,你可以直接复制运行。


1. HTML基础结构

先准备一个canvas用来输出计算结果:

<canvas id="glCanvas" width="512" height="512"></canvas>

2. JavaScript部分(WebGL上下文初始化与调度)

这部分负责创建WebGL上下文、编译着色器、设置渲染状态,最后触发GPU的并行计算:

// 获取canvas和WebGL上下文
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');

if (!gl) {
  alert('你的浏览器不支持WebGL');
  throw new Error('WebGL not supported');
}

// 顶点着色器代码(负责传递全屏顶点位置)
const vertexShaderSource = `
attribute vec2 a_position;

void main() {
  gl_Position = vec4(a_position, 0.0, 1.0);
}
`;

// 片元着色器代码(核心并行计算逻辑在这里!)
const fragmentShaderSource = `
precision mediump float;

uniform vec2 u_resolution;

void main() {
  // 把像素坐标转换到0.0-1.0的归一化范围
  vec2 st = gl_FragCoord.xy / u_resolution;
  
  // 并行计算:每个像素独立计算x和y的平方值
  float xSquare = st.x * st.x;
  float ySquare = st.y * st.y;
  
  // 把计算结果转换成颜色输出(红= x平方,绿= y平方,蓝=0)
  gl_FragColor = vec4(xSquare, ySquare, 0.0, 1.0);
}
`;

// 编译着色器的工具函数
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('着色器编译失败:', gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

// 创建并链接着色器程序
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  console.error('程序链接失败:', gl.getProgramInfoLog(program));
  gl.deleteProgram(program);
  return;
}

// 设置全屏顶点数据(覆盖整个canvas的两个三角形)
const vertices = new Float32Array([
  -1.0, -1.0,
   1.0, -1.0,
  -1.0,  1.0,
  -1.0,  1.0,
   1.0, -1.0,
   1.0,  1.0,
]);

const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 获取着色器中的属性和Uniform变量位置
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
const resolutionUniformLocation = gl.getUniformLocation(program, 'u_resolution');

// 准备渲染环境
gl.useProgram(program);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

// 传递canvas分辨率给片元着色器
gl.uniform2f(resolutionUniformLocation, canvas.width, canvas.height);

// 清空画布并触发绘制(这一步会让GPU并行处理所有片元)
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);

3. 核心并行逻辑解释

这个例子的并行性完全体现在片元着色器里:

  • 当调用gl.drawArrays时,GPU会同时启动成千上万个独立的“计算线程”,每个线程对应canvas上的一个像素(片元)。
  • 每个线程独立执行main()函数内的代码:计算自己对应像素的坐标平方,再转换成颜色输出。这些计算完全没有依赖关系,GPU可以同时处理所有片元,效率远高于CPU单线程。
  • 你可以把平方计算换成任何需要并行处理的任务(比如矩阵运算、图像滤镜、数据加密),只要每个任务是独立的,都能用这种方式让GPU并行处理。

内容的提问来源于stack exchange,提问作者Lance Pollard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 07:04:23