WebGL可视化基础(一)
图形是如何绘制的
一个通用的计算机图形系统主要包括6个设备,分别是输入设备/中央处理单元/图形处理单元/存储器/帧缓存/输出设备
首先,数据经过CPU处理,转换为特定结构的几何信息,然后将这些信息送到GPU中进行处理。在GPU中要经过两个步骤生成光栅信息。这些光栅信息会输出到缓存中,最后渲染到屏幕上。
这个绘图过程主要做了2件事情,一是对给定的数据结合绘图的场景要素(例如相机/光源/遮挡物体等等)进行计算,最终将图形变为屏幕空间的2D坐标。二是为屏幕空间的每个像素点进行着色,把最终完成的图形输出到显示设备上。这整个过程是一步一步进行的,前一步的输出就是后一步的输入,所以我们也把这个过程叫做渲染管线(RenderPipelines)
如何用WebGL绘制三角形
浏览器提供的WebGL API是IpenGL ES的 JavaScript绑定版本,它赋予开发者操作GPU的能力。
-
创建WebGL 上下文 -
创建WebGL 程序 -
将数据存入缓冲区 -
将缓冲区的数据读取到GPU -
GPU执行WebGL程序,输出结果
步骤一:创建WebGL上下文
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");
步骤二:创建WebGL 程序
-
这里需要创建一个WebGLProgram 对象,它是给GPU最终运行着色器的程序。
-
这里首先要编写两个着色器(Shader)。
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绘制一个图形的过程,一般都需要用到两段着色器。一段叫顶点着色器负责处理图形的顶点信息,另一段叫片元着色器负责处理图形的像素信息。
我们可以把顶点着色器理解为处理顶点的GPU程序代码。他可以改变顶点的信息(如顶点的坐标/法线方向/材质等等),从而改变我们绘制出来的图形的形状或者大小等
顶点处理完之后,WebGL就会根据顶点和绘图模式指定的图元,计算出需要着色的像素点,然后对它们进行执行片元着色器程序。
这里其实很好理解,顶点是为了帮助我们绘制出图形,图元是为了帮助我们上色。
-
开始绘制三角形
// 创建成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程序上。
// 再将WebGL程序链接到WebGL上下文对象上。
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgrram(program);
// 最后通过useProgram 选择启动这个WebGLPrame对象。
gl.useProgram(program);
// 接下来将数据存入缓冲区,也就是将数据送入GPU
// 定义三角形的三个顶点
const points = new Float32Array([
-1, -1,
0, 1,
1, -1,
]);
// 将数据送入WebGL的缓冲区 三步走,创建一个缓存对象,绑定为当前操作对象,再把当亲的数据写入缓存对象。
const bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
// 将缓存区数据读取到GPU,把数据绑定给顶点着色器的position变量
// 在GLSL中, attribute 表示声明变量,vec2是变量的类型,它表示一个二维向量,position是变量名。
const vPosition = gl.getAttribLocation(program, 'position');
// 获取顶点着色器中的position
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0); //给变量设置长度和类型
gl.enableVertextAttribArray(vPosition); //激活变量
// 执行着色器程序完成绘制
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);
// 至此我们的三角形就绘制完成了
-
WebGL 绘图过程流程图
参考文章
极客时间:跟月影学和石化