Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript WebGL 基础概念 #108

Open
XXHolic opened this issue Nov 6, 2021 · 0 comments
Open

JavaScript WebGL 基础概念 #108

XXHolic opened this issue Nov 6, 2021 · 0 comments

Comments

@XXHolic
Copy link
Owner

XXHolic commented Nov 6, 2021

目录

引子

看了一个库的源码,里面用到了 WebGL ,就开始找 WebGL 的资料。发现相关的知识点很多,按照自己的理解习惯进行了整理记录。

简介

WebGL 是一个跨平台、免费的开放式 Web 标准,用于基于 OpenGL ES 的初级 3D 图形 API 。可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。在 JavaScript 中可以通过 HTML5 的 Canvas 元素使用。WebGL 1.0 基于 OpenGL ES 2.0,WebGL 2.0 基于 OpenGL ES 3.0 。目前浏览器支持情况见Can I use WebGL ?

WebGL 官方相关引导资源见这里,感觉浏览加载有些慢,单独下载了一份到 Github : WebGL 1.0WebGL 2.0

OpenGL ES 是一个跨平台、免费的 API ,用于在嵌入式和移动系统(包括控制台、手机、设备和车辆)上渲染高级 2D 和 3D 图形。它是 OpenGL 的子集。

OpenGL 是业界最广泛采用的 2D 和 3D 图形 API ,为各种计算机平台带来了数千种应用程序。它独立于窗口系统和操作系统。OpenGL 公开了最新图形硬件的所有功能。

OpenGL 规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现的,将由 OpenGL 库的开发者自行决定,因此在不同系统中相同的 API 可能会出现表现行为不一致的情况。

OpenGL ES 对应的可编程语言是 OpenGL ES Shading Language (GLSL ES),该语言基于 OpenGL Shading Language (GLSL) 制定。GLSL 是 OpenGL 的主要着色语言,其风格类似 C 语言,是为图形计算量身定制的,它包含一些针对向量和矩阵操作的有用特性。

下面的概念大都是关于 OpenGL ,由于 WebGL 核心还是基于 OpenGL ,同样有助于理解。

状态机

状态机(FSM)是一个计算数学模型,是一个抽象的机器,能在任何给定的时间处于有限状态中的一个。FSM 可以根据一些输入从一种状态改变到另一种状态。

OpenGL 自身就是一个巨大的状态机:一系列的变量描述 OpenGL 此刻应当如何运行。在 OpenGL 相关程序中可以看到很多全局的变量,其中一些是输出变量,一些输入变量。

图形渲染管线

在 OpenGL 中,任何事物都在 3D 空间中,而屏幕和窗口却是 2D 像素,这导致 OpenGL 的大部分工作都是关于把 3D 坐标转变为适应屏幕的 2D 像素。3D 坐标转为 2D 坐标的处理过程是由 OpenGL 的图形渲染管线(Graphics Pipeline)管理。

图形渲染管线可以被划分为几个阶段,每个阶段将会把前一个阶段的输出作为输入。所有这些阶段都是高度专门化的,并且很容易并行执行。正是由于它们具有并行执行的特性,当今大多数显卡都有成千上万的小处理核心,它们在 GPU 上为每一个(渲染管线)阶段运行各自的小程序,从而在图形渲染管线中快速处理数据。这些小程序叫做着色器(Shader)。

下面是一个图形渲染管线的每个阶段的抽象展示。注意蓝色部分代表可以注入自定义着色器,也就是可编程。

91-pipeline

作为图形渲染管线输入的数据叫做顶点数据(Vertex Data)。顶点数据是一系列顶点的集合。一个顶点(Vertex)是一个 3D 坐标数据的集合。而顶点数据是用顶点属性(Vertex Attribute)表示的,它可以包含任何我们想用的数据。

输入的数据会进入到图形渲染管线的第一个处理阶段:顶点着色器。

顶点着色器

顶点着色器(Vertex Shader)可编程,主要的目的是把 3D 坐标转为标准化设备坐标。还会在 GPU 上创建内存用于储存顶点数据,还要配置 OpenGL 如何解释这些内存,并且指定其如何发送给显卡。顶点着色器允许我们对顶点属性进行一些基本处理。

顶点相关的信息都存放在顶点缓冲对象(Vertex Buffer Objects, VBO)中,它会在 GPU 内存(通常被称为显存)中储存大量顶点。使用这些缓冲对象的好处是可以一次性发送一大批数据到显卡上,而不是每个顶点发送一次。当数据发送至显卡的内存中后,顶点着色器几乎能立即访问顶点,这是个非常快的过程。

接着进入到图元装配阶段。

图元装配

图元装配(Primitive Assembly)将顶点着色器输出的所有顶点作为输入,所有的点会装配成指定图元的形状。图元基本形状有:

  • 线
  • 三角形

图元装配阶段的输出会传递给几何着色器阶段。

几何着色器

几何着色器(Geometry Shader)可编程,把图元形式的一系列顶点的集合作为输入,它可以通过产生新顶点构造出新的(或是其它的)图元来生成其它形状。

几何着色器的输出会被传入光栅化阶段。

光栅化

光栅化(Rasterization)会把图元映射为最终屏幕上相应的像素,生成供片元着色器使用的片元(Fragment)。在片元着色器运行之前会执行裁切(Clipping)。裁切会丢弃超出视图以外的所有像素,用来提升执行效率。

片元着色器

片元着色器(Fragment Shader)可编程,主要目的是计算一个像素的最终颜色,这也是所有 OpenGL 高级效果产生的地方。通常,片元着色器包含 3D 场景的数据(比如光照、阴影、光的颜色等等),这些数据可以被用来计算最终像素的颜色。

在所有对应颜色值确定以后,最终的对象将会被传到最后一个阶段:测试混合。

测试混合

测试混合(Tests And Blending)阶段检测片元的对应深度(和模板(Stencil))值,用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。这个阶段也会检查 alpha 值(alpha值定义了一个物体的透明度)并对物体进行混合(Blend)。所以,即使在片元着色器中计算出来了一个像素输出的颜色,最后渲染的像素颜色也可能完全不同。

WebGL 中的着色器

WebGL 中主要编写的着色器有顶点着色器和片元着色器。具体实现见 JavaScript WebGL 绘制一条直线

参考资料

🗑️

最近看了《秘密花园》,很有趣,是一种顿时空滞,然后突然转变的有趣。

发现矢口史靖后续的作品,基本都是延续了这个风格。

91-poster

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant