乐趣区

关于javascript:可视化WebGL绘制最简单的图形你了解多少一

你好,这是一篇硬核文章。须要潜心浏览,如果你感觉有用请点赞珍藏!

明天,咱们要讲的是 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 的坐标系。

预知后续如何请听下回分解 …

退出移动版