OpenGL学习笔记

名词概念

名词部分,可以参考WebGL Fundamentals

DirectX VS. OpenGL

OpenGL:开放的图形库(Open Graphic Library)。如其名,它的作用,就是绘制图形,除此之外都不做。

DirectX:专门适配windows平台的OpenGL,是微软定义的一个标准,基于微软的COM组件框架。

Metal 3D:专门适配Mac平台的OpenGL

OpenGL ES:专门适配嵌入式设备(手机、平板)的OpenGL

OpenGL是跨平台的,windows、Mac、Linux、iOS、Android等等大家都能用。但所谓泛而不精,微软为了更好的性能,开发出了一套专门适配windows平台的OpenGL,名为DirectX。同理,苹果在今年也开发出了一套专门适配Mac和iOS平台的OpenGL,名为Metal 3D。

矩阵变换

渲染管线

所谓的渲染管线,实际上就是渲染过程流水线,指的不是具体某一样东西,而是一个流程。shader实际上只是渲染流程中的一个小小的,可编程的片段。

实际上就是模型信息到最终屏幕的一个过程。

参考这个文章:https://zhuanlan.zhihu.com/p/61216531

graph LR
    a(硬盘) --> b(出来) --> c(一个三角面片) --> d(走进) --> e(CPU) --> f(三角面片) --> g(GPU) --> h(光栅化) --> i(显示器)

Primitive(图元)

一般叫做Geometry Primitive(几何图元)

Rasterization(光栅化)

读音 /ˈræstəraɪz/

“光栅化”其实就是“用像素画出来” 的花哨叫法。

默认光线只反射一次,从而可以把反射计算整个放在二维图像空间里做,二维图像就是所谓的“光栅”

Shader(着色器)

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

着色器本质上是一种运行在显卡 CPU 上的程序,用于控制显卡的图形渲染过程。CPU 运行的程序通常用汇编语言,或者 C++、Java 等高级语言编写。GPU 采用的是不同于 CPU 的并行计算结构,需要一种适用于 GPU 的编程语言,于是就有了着色器语言。

Asset是设计师做的资产(数据),Source是程序员写的程序,而Shader可以理解为程序员写的资产(数据)。

Vertex shader(顶点着色器)

描述顶点特性(位置,尺寸),主要就是把顶点坐标从模型空间变换到齐次裁剪空间。

Pixel shader(像素着色器)

Geometry shader(几何着色器)

几何着色器Geometry shader可以操作几何上的图元。几何着色器以图元作为输入,就像顶点着色器以顶点作为输入。在渲染管线顺序中,几何着色器就夹在顶点着色器和像素着色器中间。

Compute shader(计算着色器)

Compute shader是一个通用的着色器,它使用在渲染管线之外,即它不是用来绘制一个图元或渲染像素的。那它是用与什么的呢?Compute shader利用GPUs的并行计算处理能力来做通用计算任务。

Tessellation or hull shader(细分曲面着色器)

Tessellation shader主要用于细分网格。

Fragment shader(片元着色器)

描述 片元(像素)处理过程

为什么我们需要Shader?

当我们在屏幕上绘制或显示一些物体时,这些物体的显示形式是图元Primitives或者网格Mesh。比如游戏中一个几何模型角色或一个贴在网格上的纹理角色,比如我们做阴影效果时先绘制网格再计算阴影,比如一个发射物体发射前需要先绘制该物体外形网格。这些物体都可归结为网格Mesh,它可被分解为图元Privitive,即图元是网格的基本单位。图元有三角形、直线或点。

MVP(Model View Projection)

模型、视图、投影矩阵

https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API/WebGL_model_view_projection

WebGL / OpenGL / ES X.0之间的关系

OpenGL(Open Graphics Library) 一种图形应用程序编程接口规范(Application Programming Interface,API)。它是一种可以对图形硬件设备特性进行访问的软件库,OpenGL被设计为一个现代化的、硬件无关的接口,因此我们可以在不考虑计算机操作系统或窗口系统的前提下,在多种不同的图形硬件系统上,完全通过软件的方式实现OpenGL的接口。

OpenGL ES(embedded system) OpenGL ES是OpenGL的一个特殊版本,主要针对嵌入式设备使用,专用于嵌入式计算机、智能手机、家用游戏机等设备。OpenGL ES 2003-2004年被首次提出来,其中两次重要升级分别在2007年(OpenGL ES 2.0)和2012年(OpenGL ES 3.0),WebGL就是基于OpenGL ES 2.0的。

OpenGL ES

内容摘自维基百科:

OpenGL ESOpenGL for Embedded Systems)是三维图形应用程序接口OpenGL的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。该API由科纳斯组织定义推广,科纳斯是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。

OpenGL ES是从OpenGL裁剪定制而来的,去除了glBegin/glEnd,四边形(GL_QUADS)、多边形(GL_POLYGONS)等复杂图元等许多非绝对必要的特性。经过多年发展,现在主要有两个版本,OpenGL ES 1.x针对固定管线硬件的,OpenGL ES 2.x针对可编程管线硬件。OpenGL ES 1.0是以OpenGL 1.3规范为基础的,OpenGL ES 1.1是以OpenGL 1.5规范为基础的,它们分别又支持common和common lite两种profile。lite profile只支持定点实数,而common profile既支持定点数又支持浮点数。OpenGL ES 2.0则是参照OpenGL 2.0规范定义的,common profile发布于2005-8,引入了对可编程管线的支持。OpenGL ES 3.0于2012年公布,加入了大量新特性。

CUDA

Compute Unified Device Architecture

统一计算设备架构

是Nvidia的一种通用并行计算架构

HLSL、GLSL、WGSL

HLSL:High-level Shading Language(高级着色器语言)

GLSL:OpenGL Shading Language(OpenGL着色器语言)

WGSL:WebGPU Shading Language(WebGPU着色器语言)

WebGL

WebGL的本质 —— JavaScript操作OpenGL接口

WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染(部分计算GPU),这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。

WebGL API基于OpenGL ES 2.0的实现。

WebGL是光栅引擎。

WebGL2

启动于2013年,2017年正式推出,已死,别再用了,也没必要学习

只支持 WebGL 2.0,这点比较致命,导致无法在 iOS 的浏览器上使用,看了一下它有调用 glDrawBuffers,但不清楚用于做什么。

WebGL 2.0 相当缓慢的发展,使得 WebGL 引擎的技术也停滞不前,前面提到过 WebGL 1.0 缺少很多重要功能,比如 Draw Buffers、Occlusion queries 等现代渲染引擎优化性能所依赖的技术,而 WebGL 2.0 的发展又极其缓慢,尽管启动于 2013 年,但直到 2017 年才正式推出,要知道 OpenGL 的替代者 Vulkan 是在 2016 年推出的,所以 WebGL 2.0 还没发布就面临被淘汰,加上 Apple 的刻意打压,至今 Safari 在桌面和 iOS 上都不默认开启 WebGL 2.0,所以 WebGL 2.0 几乎没人使用,用也只能用那些支持面比较广的 WebGL 1.0 扩展功能。

Intel 公司曾提交了 WebGL 2.0 Compute 标准,该标准来自 OpenGL ES 3.1 Compute
但只有 Chrome 浏览器实现了这一标准,Chrome 团队在实现 WebGL 2.0 Compute 时遇到了巨大的阻力
本质是因为 WebGL 并不与现代 GPU 的设计理念匹配,导致了很多 CPU 和 GPU 性能问题
Intel 公司决定停止继续开发 WebGL 2.0 Compute,而将注意力转移到 WebGPU 上
Google 已经将 WebGL 2.0 Compute 支持从 Chrome 中移除,该标准已经名存实亡

WebGPU

思考:我们如果要做元宇宙,就应该用WebGPU,那么技术选型上,就得选择Babylon,而不是Three.js

不过目前WebGPU1.0尚未发布,浏览器也还没正式支持,可能初期还是得用Three.js,后面再重写么?神经病…应该一开始就用Babylon。

【精】可以参考这个人的PPT:https://hjlld.github.io/gmtc-2021-webgpu-slide/

WebGPU是最新的Web 3D图形API,浏览器封装了现代图形API(Dx12、Vulkan、Metal),是未来的标准。

WebGPU 摆脱了状态机机制,新增 Pipeline、Renderpass、CommandEncoder 等对象,面对对象编程、增加异步支持,改善验证机制……

Web的下一代技术,目前前端3D引擎,只有Babylon支持,其他都不支持Three.js也支持了,这是官方的Demo.

最新版的Chrome和Firefox都还不支持WebGPU,想要测试得用特殊版本的浏览器才行。因此距离真正商用,还有一段路要走。

和WebGL的性能对比:

其他对比:

vs

Vulkan

OpenGL的替代者,2016年推出

对游戏的效果和帧数的影响:效果不变,帧数提高。

延迟渲染

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

游戏引擎

游戏引擎在渲染器的基础上增加了面向游戏开发的各种功能,包括 AI、物理、编辑器等,工作量巨大,比起图形学算法,更重要还有工程能力。

烘焙

是为了解决全局光照导致的性能问题。

将光照的效果,体现在贴图上,这样就省去了全局光照的计算量,性能上有极大的提升。

UV纹理贴图坐标

U、V纹理贴图坐标,(它和空间模型的X, Y, Z轴是类似的),它定义了图片上每个点的位置的信息. 这些点与3D模型是相互联系的, 以决定表面纹理贴图的位置, UV就是将图像上每一个点精确对应到模型物体的表面, 在点与点之间的间隙位置由软件进行图像光滑插值处理, 这就是所谓的UV贴图。

UV就是一张二维图像,UV映射就是将二维图像投影到三维模型的表面以进行纹理映射的3D建模过程。

U代表水平方向,V代表垂直方向,所以U和V就代表了2D纹理的轴,而 X,Y,Z 则用于表示三维模型空间中3D对象的轴。

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

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

一句话经验

OpenGL自身是一个巨大的状态机(State Machine):一系列的变量描述OpenGL此刻应当如何运行。

资料

Learn OpenGL:

https://learnopengl-cn.github.io/

基于OpenGL的GPU光线追踪:

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

20分钟让你了解OpenGL——OpenGL全流程详细解读:

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