你好,这是一篇硬核文章。须要潜心浏览,如果你感觉有用请点赞珍藏!
明天,咱们要讲的是 WebGL。
WebGL 图形系统,也是最难学的一个。为啥说它难学呢?我感觉这次要有两个起因。
1.WebGL 这种技术自身就是用来解决最简单的视觉出现的。比如说,大批量绘制简单图形和 3D 模型,这类比拟有难度的问题就适宜用 WebGL 来解决。
2.WebGL 绝对于其余图形系统来说,是一个更凑近底层的零碎。因为,不论是 HTML/CSS、SVG 还是 Canvas,都次要是应用其 API 来绘制图形的,所以咱们不用关怀它们具体的底层机制。
3.咱们只有了解创立 SVG 元素的绘图申明,学会执行 Canvas 对应的绘图指令,可能将图形输入,这就够了。
4.要应用 WebGL 绘图,咱们必须要深刻细节里。咱们必须要和内存、GPU 打交道,真正管制图形输入的每一个细节。
5.想要学好 WebGL,咱们必须先了解一些基本概念和原理。那明天,我会从图形系统的绘图原理开始讲起,次要来讲 WebGL 最根底的概念,包含 GPU、渲染管线、着色器。而后,我会带你用 WebGL 绘制一个简略的几何图形。心愿通过这个可视化的例子,可能帮忙你了解 WebGL 绘制图形的基本原理,打好绘图的根底。
图形系统是怎么绘图的?
咱们来说说计算机图形系统的次要组成部分,以及它们在绘图过程中的作用。晓得了这些,咱们就能很容易了解计算机图形系统绘图的基本原理了。
一个通用计算机图形系统次要包含 6 个局部,别离是 输出设施、地方处理单元、图形处理单元、存储器、帧缓存和输出设备。
光栅(Raster):简直所有的古代图形系统都是基于光栅来绘制图形的,光栅就是指形成图像的像素阵列。
像素(Pixel):一个像素对应图像上的一个点,它通常保留图像上的某个具体位置的色彩等信息。
帧缓存(Frame Buffer):在绘图过程中,像素信息被寄存于帧缓存中,帧缓存是一块内存地址。
CPU(Central Processing Unit):地方处理单元,负责逻辑计算。
GPU(Graphics Processing Unit):图形处理单元,负责图形计算。
晓得了这些概念,我带你来看一个典型的绘图过程,帮你来清晰一下这些概念的理论用处。
首先,数据通过 CPU 解决,成为具备特定构造的几何信息。
而后,这些信息会被送到 GPU 中进行解决。在 GPU 中要通过两个步骤生成光栅信息。这些光栅信息会输入到帧缓存中,最初渲染到屏幕上。
这个绘图过程是古代计算机中 任意一种图形系统解决图形的通用过程。它次要做了两件事。
1. 一是对给定的数据联合绘图的 场景因素(例如相机、光源、遮挡物体等等)进行计算 ,最终将图形变为屏幕空间的 2D 坐标。
2. 二是为屏幕空间的每个 像素点进行着色,把最终实现的图形输入到显示设施上。这整个过程是一步一步进行的,前一步的输入就是后一步的输出,所以咱们也把这个过程叫做渲染管线(RenderPipelines)。在这个过程中,CPU 与 GPU 是最外围的两个处理单元,它们参加了计算的过程。
上面绘图实战来了,请筹备好小凳子
WebGL 残缺的绘图过程切实比较复杂,为了帮忙你了解,请先理解绘图流程后而后再进行代码编写!
1. 创立 WebGL 上下文
创立 WebGL 上下文这一步和 Canvas2D 的应用简直一样。
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
2. 创立 WebGL 程序
这里的 WebGL 程序是一个 WebGLProgram 对象,它是给 GPU 最终运行着色器的程序,而不是咱们正在写的三角形的 JavaScript 程序。
要创立这个 WebGL 程序,咱们须要编写两个着色器(Shader)。着色器是用 GLSL 这种编程语言编写的代码片段,这里咱们先不必过多纠结于 GLSL 语言,在后续的课程中咱们会具体解说。那在这里,咱们只须要了解绘制三角形的这两个着色器的作用就能够了。
const vertex = `
attribute vec2 position;
void main() {
gl_PointSize = 1.0;
gl_Position = vec4(position, 1.0, 1.0);
}
`;
const fragment = `
precision mediump float;
void main()
{gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
那咱们为什么要创立两个着色器呢?这就须要咱们先来了解 顶点和图元 这两个基本概念了。
在绘图的时候,WebGL 是以顶点和图元来形容图形几何信息的 。
顶点就是几何图形的顶点,比方,三角形有三个顶点,四边形有四个顶点。
图元是 WebGL 可间接解决的图形单元,由 WebGL 的绘图模式决定,有点、线、三角形等等。
因而,WebGL 绘制一个图形的过程,个别须要用到两段着色器,
一段叫 顶点着色器(Vertex Shader)负责解决图形的顶点信息,
另一段叫 片元着色器(Fragment Shader)负责解决图形的像素信息。
更具体点来说,咱们能够把顶点着色器了解为解决顶点的 GPU 程序代码。
它能够扭转 顶点的信息(如顶点的坐标、法线方向、材质等等),
从而扭转咱们绘制进去的图形的形态或者大小等等。
顶点解决实现之后,WebGL 就会依据 顶点和绘图模式指定的图元,计算出须要着色的像素点 ,而后对它们执行片元着色器程序。
简略来说,就是对指定图元中的像素点着色。WebGL 从顶点着色器和图元提取像素点给片元着色器执行代码的过程,就是咱们后面说的生成光栅信息的过程,咱们也叫它光栅化过程。所以,片元着色器的作用,就是解决光栅化后的像素信息。
创立着色器的 目标 是为了创立 WebGL 程序,那咱们应该如何用顶点着色器和片元着色器代码,来创立 WebGL 程序呢?首先,因为在 JavaScript 中,顶点着色器和片元着色器只是一段代码片段,所以咱们要将它们别离创立成 shader 对象。代码如下所示:
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);
接着,咱们 创立 WebGLProgram 对象,并将这两个 shader 关联到这个 WebGL 程序上。WebGLProgram 对象的创立过程次要是增加 vertexShader 和 fragmentShader,而后将这个 WebGLProgram 对象链接到 WebGL 上下文对象上。代码如下:
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
最初,咱们要通过 useProgram 抉择 启用这个 WebGLProgram 对象。这样,当咱们绘制图形时,GPU 就会执行咱们通过 WebGLProgram 设定的 两个 shader 程序了。
gl.useProgram(program);
好了,当初咱们曾经创立并实现 WebGL 程序的配置。接下来,咱们只有将三角形的数据存入缓冲区,也就能将这些数据送入 GPU 了。那实现这一步之前呢,咱们先来认识一下 WebGL 的坐标系。
预知后续如何请听下回分解 …