共计 3885 个字符,预计需要花费 10 分钟才能阅读完成。
明天由字节跳动的 ”yancy” 童鞋给大家重磅推出一篇 WebGL
的干货接下来让咱们开启奇幻旅程,进入 3D
的世界。
本文作者:yancy
1. 意识3D
首先咱们要介绍的是几个概念,这是咱们要进入到 3D
不可或缺的内容。认识一下它们吧。
1.1 视点,眼帘,指标点,上方向
这几个概念在 WebGL
中属于最常见的内容。
- 视点:能够繁难的了解为眼睛,也叫观察点
- 指标点:能够了解为咱们要看的物体(任何物体)
-
上方向:头顶的方向。
理论生存中,咱们的眼光总是以咱们的眼睛为起始点,达到咱们想要看到的物体,同时,随着咱们察看的角度不同,物体也会出现不一样的状态。以一张图阐明吧。
如此几个内容,创立出了3D
世界的根本显示模型,由此可见其重要水平。前面咱们也会说到如何在WebGL
中设定这几个内容。也会有的小伙伴把 视点称为相机 , 指标点称为画布。其实是一样的情理。依照本人的了解记忆就好。1.2 可视范畴
可视范畴指的是咱们所能看到的最大范畴。如:个别状况下咱们看不到本人身后的事物。
家喻户晓,三维物体具备深度的概念。在咱们的了解中,深度就是z
轴。
尽管咱们能够将物体搁置在三维空间中的任何地位,然而在WebGL
中,可视范畴之外的物体是不被绘制的,这也是为了节俭开销。1.3 可视空间
程度视角、垂直视角、可视深度
定义了可视空间的概念。
可视空间分为两种。 - 正射投影:与物体的远近无关,通常用在建筑设计和建模上。
-
透视投影:咱们平时察看的真实世界都是透视投影。更有深度的感觉。
1.3 着色器
如果想渲染
3D
图形,就须要通过一系列的步骤,这些步骤称为渲染管线。在开发WebGL
程序时,咱们就须要通过着色器语言跟 GPU 进行沟通,用来设定咱们须要渲染和显示的图形。
由此可见:着色器是编写WebGL
时最重要的一点(没有之一)。咱们之所以能生成并操作3D
图像,都是因为着色器在起作用。WebGL
中着色器分为两种。顶点着色器和片元着色器。1.3.1 顶点着色器
这里的顶点代表的是组成物体的每一个点。
顶点着色器的性能次要是将地位数据通过矩阵变换、计算光照之后生成顶点色彩、变换纹理坐标。并将生成的数据输入到片元着色器。1.3.2 片元着色器
片元着色器的作用是将 光栅化阶段 生成的每个片元,计算出每个片元的最终元素。
注:
因为着色器内容比拟重要,这里咱们先引入这两个概念,先简略了解就能够,前面专门对着色器进行分享。2. 绘制图形
2.1 获取绘图上下文
理解了第一大节的内容之后,咱们开始进入到
WebGL
开发实战中。
还记得Canvas
中第一步须要干什么吗?
没错,须要获取Canvas
元素和绘图上下文。WebGL
开发也不例外,也须要首先获取元素和绘图上下文。形如下方代码所示:2.2 初始化着色器
2.2.1. 编写着色器代码
获取到绘图上下文之后,咱们须要初始化
WebGL
的着色器了, 着色器代码是以字符串的模式嵌入到渲染程序中 ,所以咱们须要编写两个着色器的字符串。
两个着色器代码都是以字符串的模式存在,并在执行渲染时嵌入到渲染流程内。
阐明: void main() {}
: 创立一个主函数。gl_Position
: 指定绘制的坐标,接管一个领有 4 个浮点重量的vec4
数据。别离代表x,y,z,w
数据gl_PointSize
: 示意要绘制图形的尺寸大小。-
gl_FragColor
: 定义图形色彩,1.0 0.0 0.0 1.0
别离代表r g b a
2.2.2. 创立着色器
当然,只是编写完着色器代码仍然不能实现渲染工作,接下来咱们就须要将着色器增加到渲染流程内
2.2.3. 着色器编译
实现上述两步之后,咱们就须要将着色器代码增加到着色器中。看下例子。
2.2.4. 创立 program
实现编译之后,咱们须要将着色器增加到渲染程序中。
2.2.5. 绘制图形
实现上述步骤之后,就能够绘制咱们的图形了。这里咱们以一个点为例。在画布上绘制一个点进去。
gl.drawArrays(gl.POINTS, 0, 1);
此时就能够关上页面,看到咱们绘制的这个点了。
总结代码:3. 渲染管线
3.1 根底内容介绍
WebGL
的渲染依赖底层GPU
的渲染能力。所以WebGL
渲染流程和GPU
外部的渲染管线是相符的。
渲染管线的作用是将 3D 模型转换为 2 维图像。
在晚期,渲染管线是不可编程的,叫做 固定渲染管线 ,工作的细节流程曾经固定,批改的话须要调整一些参数。
古代的GPU
所蕴含的渲染管线为 可编程渲染管线,能够通过编程GLSL,着色器语言
来管制一些渲染阶段的细节。3.2 渲染过程
(心理接受弱的同学可跳过此大节)
WebGL
的渲染过程分为以下几项: - 顶点着色器
- 图片拆卸
- 光栅化
- 片元着色器
-
逐片段操作(本文不会分享此内容)
- 裁剪测试
- 多重采样操作
- 反面剔除
- 模板测试
- 深度测试
- 交融
-
缓存
这里一系列的名词可能会吓到很多同学,千万别被名词吓到哟,接下来的过程中会具体阐明。也心愿通过本文能够让大家了解根本的渲染流程。附图解一张,助大家了解。4. 顶点着色器
顶点着色器的作用是通过计算取得最终的顶点坐标,如:
A --> () => {…………} ==> A1
:坐标A
通过一系列的计算,最终获取坐标A1
B --> () => {…………} ==> B1
:坐标B
通过一系列的计算,最终获取坐标B1
- …………
顶点着色器计算出来的坐标将会渲染到最终的显示画布上。
此外,顶点着色器还会计算如下内容:色彩、纹理坐标、顶点尺寸……
在顶点着色器阶段通常会波及到三个类型的变量。 -
attribute:针对繁多顶点失效。
- 通常用于:顶点地位、顶点大小等内容
-
uniform:影响所有顶点
- 通常用于:旋转、平移、缩放等地位变换、色彩解决等内容。
-
varying:可通过顶点着色器传入到片元着色器。
像attribute
这个变量之前咱们就用到过,用来设置了顶点的地位和大小。回顾一下
其余的两个变量临时没有用到,接下来的内容里会用到这两种类型的变量。敬请期待😁5. 图元拆卸和光栅化
什么是图元?
官网解释:
形容各种图形元素的函数叫做图元,形容几何元素的称为几何图元(点,线段或多边形)。点和线是最简略的几何图元
通过顶点着色器计算之后的坐标会被组装成 组合图元。
接下来通过一组图解来看看渲染器如何进行图元拆卸和光栅化
艰深解释
图元就是一个点、一条线段、或者是一个多边形。
5.1 图元拆卸
什么是图元拆卸呢?
简略了解就是说将咱们设置的顶点、色彩、纹理等内容组装称为一个可渲染的多边形的过程。
留神:
如何组装取决于gl.drawArrays(type, count)
中的type
类型,本文最初有具体的内容。
在之前的文章里,咱们就应用gl.POINTS
来绘制了一个点。5.2 光栅化
片元:二维图象上每个点都蕴含了色彩、深度和纹理数据。这样一个点称为片元
光栅化能够简略了解为以下内容:
通过图元拆卸生成的多边形,计算像素并填充,剔除 不可见的局部,剪裁 掉不在可视范畴内的局部。最终生成可见的带有色彩数据的图形并绘制。
光栅化流程图解:剔除和剪裁
-
剔除:举一个日常生活中的栗子来阐明吧。
- 在日常生活中,对于不通明物体,反面对于观察者来说是不可见的。同样,在
WebGL
中,咱们也能够设定物体的反面不可见,那么在渲染过程中,就会将不可见的局部剔除,不参加绘制。节俭渲染开销。
- 在日常生活中,对于不通明物体,反面对于观察者来说是不可见的。同样,在
-
剪裁:同样举例子来阐明
-
日常生活中不论是在看电视还是察看物体,都会有一个可视范畴,在可视范畴之外的事物咱们是看不到的。相似的,图形生成后,有的局部可能位于可视范畴之外,这一部分会被剪裁掉,不参加绘制。以此来进步性能。
6. 片元着色器
接管光栅化阶段生成的片元,在光栅化阶段中,曾经计算出每个片元的色彩信息,这一阶段会将片元做逐片元筛选的操作,解决过的片元会持续向前面的阶段传递。
逐片元筛选
通过模板测试和深度测试来确定片元是否要显示,测试过程中会抛弃掉局部无用的片元内容,而后生成可绘制的二维图像绘制并显示。
-
- 深度测试:就是对
z
轴的值做测试,值比拟小的片元内容会笼罩值比拟大的。(相似于近处的物体会遮挡远处物体)。 -
模板测试:模仿观察者的察看行为,能够接为镜像察看。标记所有镜像中呈现的片元,最初只绘制有标记的内容。
7. 实例剖析
上面联合 2.2.5 的代码,咱们进行流程剖析,加深了解。
剖析: - 首先创立了两个变量
VERTEX_SHADER 顶点着色器
和FRAGMENT_SHADER 片元着色器
。这两个内容会通过上面的代码增加到顶点着色器和片元着色器中。 - 之后通过
gl.createShader()
创立了两个着色器。传入不同的参数即可创立不同的着色器。创立并关联着色器的步骤比较复杂。当你相熟这个过程之后,能够将这个过程的代码封装起来作为备用。 - 接下来,通过
将着色器代码增加到着色器中、编辑着色器、创立程序对象、将着色器增加到程序对象中、关联程序对象、应用程序对象
这一系列的步骤初始化着色器和程序对象。 -
当所有的前置工作准备就绪之后,就能够调用
gl.drawArrays()
办法来绘制想要的图形。7.1 gl.drawArrays(type, first, count)
1.
type
代表要绘制的图形形态,值有以下几种:gl.POINTS: 要绘制一系列的点
gl.LINES: 要绘制了一系列未连贯直线段(独自行)
gl.LINE_STRIP: 要绘制一系列连贯的线段gl.LINE_LOOP : 要绘制一系列连贯的线段。它还连贯第一个和最初一个顶点,以造成一个环
gl.TRIANGLES: 一系列独自的三角形
gl.TRIANGLE_STRIP: 绘制一个三角带
gl.TRIANGLE_FAN: 绘制一个扇形(三角扇)
2.
first
代表从哪个点开始3.
count
代表须要应用几个点栗子:
其余的形态能够本人尝试…………会有意想不到的成果。
文章为原创文章,若有侵权请分割;