WebGL学习笔记

不管是什么形式,本质上都是3D可视化技术。所以学习WebGL,就是学习3D技术。掌握了核心思想和经验,不管是云游戏、pc端3D、web 3d,都可以快速实现。

WebGL的上限是什么?

WebGL的工作原理

这个文章介绍得很简洁明了:

https://www.cnblogs.com/wanbo/p/6754066.html

PS:这个人的文章都值得一看

函数调用栈

WebGL函数调用记录,通过Chrome Developer Tools / Canvas Profile 得到的。

–知乎用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
disableVertexAttribArray(1)
disable(BLEND)
enable(SAMPLE_ALPHA_TO_COVERAGE)
depthMask(1)
disable(BLEND)
useProgram(WebGLProgram@1)
activeTexture(TEXTURE0)
bindTexture(TEXTURE_2D, WebGLTexture@1)
uniform1i(WebGLUniformLocation@4, 0)
bindBuffer(ARRAY_BUFFER, WebGLBuffer@2)
enableVertexAttribArray(0)
vertexAttribPointer(0, 3, FLOAT, false, 12, 0)
bindBuffer(ARRAY_BUFFER, WebGLBuffer@3)
enableVertexAttribArray(1)
vertexAttribPointer(1, 2, FLOAT, false, 8, 0)
bindBuffer(ARRAY_BUFFER, WebGLBuffer@1)
enableVertexAttribArray(2)
vertexAttribPointer(2, 3, FLOAT, false, 12, 0)
bindBuffer(ELEMENT_ARRAY_BUFFER, WebGLBuffer@4)
drawElements(TRIANGLES, 780, UNSIGNED_SHORT, 0)

【精】gl绘制过程:为什么OpenGL会被淘汰

作者:四季留歌
链接:https://www.zhihu.com/question/315103318/answer/2210623439
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这是创建两大着色器并执行编译、连接的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
const vertexShaderCode = `
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
`

const fragmentShaderCode = `
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0.5, 1);
}
`

// 创建shader对象
const vertexShader = gl.createShader(gl.VERTEX_SHADER)
// 载入shader代码
gl.shaderSource(vertexShader, vertexShaderCode)
// 编译shader代码
gl.compileShader(vertexShader)

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fragmentShader, fragmentShaderCode)
gl.compileShader(fragmentShader)

// 创建Program
const program = gl.createProgram()
// 附加shader
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
// 连接
gl.linkProgram(program)

// 还需要显式指定你需要用哪个 program
gl.useProgram(program)
// 继续操作顶点数据并触发绘制
// ...

CPU 负载问题有人说这无所谓,可以封装成 JavaScript 函数,隐藏这些过程细节,只需传递参数即可。是,这是一个不错的封装,很多 js 库都做过,并且都很实用。

但是,这仍然有难以逾越的鸿沟 —— 那就是 OpenGL 本身的问题。

每一次调用gl.xxx时,都会完成 CPU 到 GPU 的信号传递,改变 GPU 的状态,是立即生效的。熟悉计算机基础的朋友应该知道,计算机内部的时间和硬件之间的距离有多么重要,世人花了几十年时间无不为信号传递付出了努力,上述任意一条 gl 函数改变 GPU 状态的过程,大致要走完 CPU ~ 总线 ~ GPU 这么长一段距离。

我们都知道,办事肯定是一次性备齐材料的好,不要来来回回跑那么多遍,而 OpenGL 就是这样子的。有人说为什么要这样而不是改成一次发送的样子?历史原因,OpenGL 盛行那会儿 GPU 的工作没那么复杂,也就不需要那么超前的设计。

随着显卡能力的提升,OpenGL的全局状态机设计离线,已经无法调用和优化先进现代显卡的能力。

综上所述,WebGL 是存在 CPU 负载隐患的,是由于 OpenGL 这个状态机制决定的。

现代三大图形API 可不是这样,它们更倾向于先把东西准备好,最后提交给 GPU 的就是一个完整的设计图纸和缓冲数据,GPU 只需要拿着就可以专注办事。

WebGL适用场景是什么?

休闲游戏、WebVR、商业营销活动、图像处理(比如一些在线设计软件,像稿定设计这种)

对于我当前的工作来说,WebGL的应用应该是侧重于特效性能这两部分,其他的都可以往后放放。

讲真,目前的WebGL应该应用价值并不大,不过我可以借此作为进入计算机图形学的一个契机,并且为5年、10年后的3D做准备。

所以明确我学习WebGL的目的和侧重点:计算机图形学&3D炫酷效果,重点搞Shader,轻语言(今后可能并不是用JS,很可能是C++)

不应该涉足的领域:3D交互工具、物联网之类的制作平台等。

我要弄明白的几个问题:

1、未来的元宇宙核心技术,可不可能在Web上体现?

技术选型

List of WebGL frameworks

  • 对于一般 WebGL 开发,推荐使用 Babylon.js。
  • 如果要支持微信小程序,最好用国内的 LayaAir 和 Cocos,但需要注意它们只是源码开放,并不是无条件免费使用,需要仔细阅读使用协议。
  • 如果只想写原生 WebGL 特效,建议用 regl。
  • 如想支持大量光源和后期特效,又不需要支持 iOS,用 Claygl。
  • 如果熟悉 Unity,直接用它导出 WebGL 也是可行的。

WebGL的局限性

几年前在 WebGL 领域中最让人印象深刻的 demo 就是 Unreal 就和 Firefox 合作的这个项目,当时我也试过,在等了十几分钟加载几十 M 的 JS 文件后终于跑起来了,但非常卡。

这个 demo 是 2014 年的,但渲染效果放到今天来看都很惊艳,秒杀绝大部分基于 Three.js/Babylon.js 开发的项目,甚至再过几年 Three.js/Babylon.js 也做不到,因为需要靠编辑器来优化间接光照。

前段时间我尝试编译过专门给移动端的 SunTemple 项目,在我的黑苹果 RX 5700 XT 上虽然不卡了,但体积太大,光引擎本身的 wasm 文件就有 82MB,数据文件也有 180MB,这样的体积是不可能放在 Web 上运行的,难怪没人用。

估计也是因为没什么人用,Unreal Engine 从 4.24 版本开始不默认提供这个功能,只作为扩展存在,交给社区,要用得自己编译一个,所以 Unreal Engine 目前已经基本放弃了 HTML5 版本。

资料

(精)如何选择 WebGL 框架和引擎?

https://blog.csdn.net/sinat_17775997/article/details/121556037

(精)WebGL理论基础:

https://webglfundamentals.org/webgl/lessons/zh_cn/

(必读)WebGPU原理介绍:

https://www.youtube.com/watch?v=y2dZYG5YTRU

(精,全是特效)Codrops:

https://github.com/codrops

WebGL BOF 2018:

https://zhuanlan.zhihu.com/p/45682197

BOF是 Birds of a Feature(一丘之貉)的缩写,是 SIGGRAPH 大会中具有相同兴趣点的人进行的线下交流,比如做 Web 的,VR 的,做医学图形的。

如何选择WebGL引擎(内含WebGL发展史):

https://zhuanlan.zhihu.com/p/162878354

WebGL编程之HelloWorld:

https://zhuanlan.zhihu.com/p/337460642

(精)WebGL&Three.js工作原理:

https://www.cnblogs.com/wanbo/p/6754066.html

WebGPU:

https://hjlld.github.io/gmtc-2021-webgpu-slide/#/

WebGL的现状与未来:

https://www.itdks.com/Home/Course/detail?id=808

(精)利用WebGL2 实现Web前端的GPU计算-含JS中WebGL的绘制流程:

https://www.xjp.in/2017/12/17/js%E7%9A%84GPU%E8%AE%A1%E7%AE%972%E4%B9%8Bwebgl/

(精)List of WebGL frameworks:

https://en.wikipedia.org/wiki/List_of_WebGL_frameworks

用TS写个FlappyBird的WebGL游戏引擎:

https://www.youtube.com/playlist?list=PLv8Ddw9K0JPiTHLMQw31Yh4qyTAcHRnJx

(精)一天写个WebGL的3D引擎-带源码(视频下面还有很多类似的挑战项目):

https://www.youtube.com/watch?v=Ms1vvo45Wi8

Awesome WebGL:

https://www.youtube.com/results?search_query=awesome++webgl

WebGL Report:

https://webglreport.com/

Three.js粒子形变(从A物体变成B物体):

https://www.cnblogs.com/wanbo/p/6869175.html

(精)艺术家:

丘墟 | SintLab