WebGL基础笔记

简介: WebGL基础笔记

WebGL基础笔记

个人参加字节跳动的青训营时写的笔记。这部分是月影老师讲的WebGL基础。

1. 简介

WebGL代码有两部分:

  • 运行在CPU上的JavaScript
  • 运行在GPU上的GLSL

CPU和GPU

  • CPU适合比较复杂的任务,不适合量大但每个单元比较简单的任务
  • GPU有大量的小运算单元构成,每个运算单元只负责处理简单的计算,每个运算单元彼此独立。所有计算可以并行处理。适合量大但每个单元比较简单的任务。

图像的处理适合交给GPU,因为图像会有很多的像素点需要处理。

2. 流程

这部分只能说似懂非懂(任重而道远啊),先贴一下课上的示例代码,方便之后看。

image-20220121161752150

  1. 创建WebGL上下文

    const canvas = document.querySelector('canvas');
    const gl = canvas.getContext('webgl');
  2. 创建WebGL程序(GLSL,顶点着色器、片元着色器)

    顶点着色器(Vertex Shader):

    image-20220121163200070

    片元着色器(Fragment Shader):顶点之间的轮廓中的所有像素都会经过片元着色器处理。(并行处理)

    image-20220121163223930

    image-20220121163501575

  3. 将数据存入缓冲区

    image-20220121163750505

  4. 将缓冲区数据读取到GPU

    ![image-20220121164109751]()

  5. GPU执行WebGL程序,输出结果

    image-20220121164208556

完整代码:

// 1. 创建WebGL上下文
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
​
// 2. 创建WebGL程序
​
// 2.1 顶点着色器
const vertex = `
  attribute vec2 position;
​
  void main() {
    gl_PointSize = 1.0;
    gl_Position = vec4(position, 1.0, 1.0);
  }
`;
​
// 2.2 片元着色器
const fragment = `
  precision mediump float;
​
  void main()
  {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }    
`;
​
// 2.3 加载、编译、使用着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);
​
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(fragmentShader);
​
​
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
​
const points = new Float32Array([
  -1, -1,
  0, 1,
  1, -1,
]);
​
// 3. 将数据存入缓存区
const bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
​
// 4. 将缓冲区数据读取到GPU
const vPosition = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosition);
​
// 5. GPU执行WebGL程序
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);  // points中有六个点,实际上只有三个点,所以需要除以2

效果:

image-20220121165503382

canvas 2D版本:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
​
ctx.beginPath();
ctx.moveTo(250, 0);
ctx.lineTo(500, 500);
ctx.lineTo(0, 500);
ctx.fillStyle = 'red';
ctx.fill();

效果和上图所示一样。(比原生WebGL简单好多)

3. 多边形

多边形需要进行三角划分

image-20220121175100166

Earcut

// 1. 创建WebGL上下文
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
​
// 2. 创建WebGL程序
​
// 2.1 顶点着色器
const vertex = `
  attribute vec2 position;
​
  void main() {
    gl_PointSize = 1.0;
    gl_Position = vec4(position, 1.0, 1.0);
  }
`;
​
// 2.2 片元着色器
const fragment = `
  precision mediump float;
​
  void main()
  {
    gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
  }    
`;
​
// 2.3 加载、编译、使用着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);
​
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(fragmentShader);
​
​
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
​
// 顶点集
const vertices = [
  [-1, -1],
  [-1, 0],
  [0, 0],
  [0, -1],
];  
​
const points = vertices.flat();  // 点集
const triangles = earcut(points);  // 三角形集(三角划分后的三角性)
​
const position = new Float32Array(points);
const cells = new Uint16Array(triangles);
​
// 3. 将数据存入缓存区,这时候需要分点和三角形来分别存
const pointBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pointBuffer);
gl.bufferData(gl.ARRAY_BUFFER, position, gl.STATIC_DRAW);
​
const cellsBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cellsBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cells, gl.STATIC_DRAW);
​
// 4. 将缓冲区数据读取到GPU
const vPosition = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosition);
​
// 5. GPU执行WebGL程序
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, cells.length, gl.UNSIGNED_SHORT, 0);  // 这部分还不是很明白
​

效果:

image-20220121184608412

4. 变换

  • 平移
  • 旋转
  • 缩放

image-20220121203813648

5. 3D标准模型的四个齐次矩阵

  • 投影矩阵
  • 模型矩阵
  • 视图矩阵
  • 法向量矩阵

挖了个大坑

6. 相关链接

相关实践学习
在云上部署ChatGLM2-6B大模型(GPU版)
ChatGLM2-6B是由智谱AI及清华KEG实验室于2023年6月发布的中英双语对话开源大模型。通过本实验,可以学习如何配置AIGC开发环境,如何部署ChatGLM2-6B大模型。
目录
相关文章
|
存储 缓存 前端开发
几个简单的小例子手把手带你入门webgl(二)
实战——绘制个三角形 在进行实战之前,我们先给你看一张图,让你能大概了解,用原生webgl生成一个三角形需要那些步骤: draw 我们就跟着这个流程图一步一步去操作: 初始化canvas 新建一个webgl画布 <canvas id="webgl" width="500" height="500"></canvas> 创建webgl 上下文: const gl = document.getElementById('webgl').getContext('webgl') 创建着色器程序 着色器的程序这些代码,其实是重复的,我们还是先看下图,看下我们到底需要哪些步骤: shader 那我们就跟着这
几个简单的小例子手把手带你入门webgl(二)
FAT32,NTFS,EXT3,支持的最大分区和单个文件大小?
FAT32 Filesystem:  最大单一档案大小 4GB 最大文件系统总容量 128GB NTFS Filesystem: 最大单一档案大小 64GB 最大文件系统总容量 2TB Ext3 Filesystem: Block 大...
8815 0
|
12天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1247 5
|
1天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
11天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1260 87