共计 5714 个字符,预计需要花费 15 分钟才能阅读完成。
download:开课吧 - 高薪 webGL 工程师 2022 最新完结无密
WebGL 是什么?
WebGL 百度百科给出的解释是 WebGL 是一个 3D 绘图协定,而维基百科给出的解释是一个 JavaScript API。因为 WebGL 技术旨在帮忙咱们在不应用插件的状况下,在任何兼容的 web 浏览器中开发交互式 2D 和 3D web 成果,因而咱们能够将其了解为帮忙咱们开发 3D 网页的绘图技术。当然,最底层是 JavaScript API。
WebGL 倒退历史
WebGL 的倒退能够追溯到 2006 年。WebGL 源于 Mozilla 员工 Vladimir Forge Sivic 的一个 Canvas 3D 试验我的项目,Canvas 3D 的原型于 2006 年首次展现。这项技术于 2007 年底在 FireFox 和 Opera 浏览器中实现。2009 年初,Khronos 团体联盟成立了 WebGL。最后的工作成员包含苹果、谷歌、Mozilla、Opera 等等。2011 年 3 月,WebGL 1.0 公布。WebGL 2 的开发始于 2013 年,最终于 2017 年 1 月实现。火狐 51、Chrome 56、Opera 43 中首次反对 WebGL 2。
总帐中的基本概念
WebGL 运行在电脑的 GPU 上,所以须要应用能在 GPU 上运行的代码。这样的代码须要提供成对的办法,其中一个叫做顶点着色器,另一个叫做切片着色器,应用 GLSL 语言。连贯顶点着色器和切片着色器的办法称为着色程序。
顶点着色器
着色器的作用是计算顶点的地位,即提供顶点在裁剪空间中的坐标值。
请参考 webglfundamentals 一文理解该模块的内容。
片段着色器
切片着色器的性能是计算图形元素的色彩值。咱们能够粗略地将切片着色器了解为网页中的像素。
数据采集模式
后面咱们提到了顶点着色器和片段着色器的概念,顶点着色器和片段着色器都须要相应的数据能力运行。接下来,让咱们看看着色器获取数据的四种形式:
和属性缓冲。
缓冲区是发送到 GPU 的二进制数据序列。通常,缓冲数据包含地位、方向、纹理坐标、顶点色彩值等。当然,你能够依据本人的须要存储任何你想要的数据。
属性用于解释如何从缓冲区获取所需的数据,并将其提供给顶点着色器。
全局变量
全局变量在着色器运行之前调配,在运行过程中全局无效。全局变量在一个绘制过程中将雷同的值传递给着色器。
静脉
纹理是一个数据序列,在着色程序运行时能够随便读取其中的数据。一般来说,咱们次要以纹理模式存储图像数据,然而除了色彩数据之外,您还能够依据本人的爱好存储其余数据。
可变变量
变量是顶点着色器将值传递给片段着色器的一种形式。
总结
WebGL 只关怀两件事: 裁剪空间的坐标值和色彩值。要应用 WebGL,只须要给它提供这两样货色。所以咱们通过提供两个着色器来做这两件事,一个顶点着色器提供裁剪空间坐标值,另一个切片着色器提供色彩值。
WebGL 的工作原理
理解了 WebGL 的一些基本概念后,咱们能够看看 WebGL 在 GPU 上做了什么。之前咱们曾经理解到,WebGL 在 GPU 上的工作次要分为两局部,即顶点着色器所做的工作 (将顶点转换为裁剪空间坐标) 和片段着色器所做的工作 (依据顶点着色器的计算结果绘制像素)。如果咱们须要画一个三角形,此时在 GPU 上做的工作就是先调用顶点着色器三次,计算三角形的三个顶点在裁剪空间坐标系中的对应地位,并通过变量 gl_Position 保留在 GPU 中,而后调用切片着色器计算每个顶点的色彩值,并通过变量 gl_FragColor 将对应的色彩值保留在 GPU 中。实现所有这些工作后,咱们失去了绘制三角形所需的像素,最终失去了栅格化的三角形。
原生 WebGL API 绘制三角形
咱们之前曾经学习了 WebGL 的历史、基本概念和工作原理,接下来是咱们实际真谛的时候了,那么咱们就来看看如何通过 WebGL 在一个网页中绘制一个简略的三角形。咱们晓得 WebGL 作为一种 3D 绘图技术,自身就是依附 HTML5 中的 canvas 元素而存在的,所以在正式开始绘图之前,咱们须要做一系列的筹备工作:
首先咱们须要创立一个 canvas 元素作为画三角形所需的画布,并实现浏览器对 canvas 元素兼容性的测试。
函数 webglInit () {
const canvasEl = document . createelement(‘ canvas ‘);// 画布元素创立
canvasel . width = document . body . client width;// 设置画布画布的宽度
canvasel . height = document . body . client height;// 设置画布 canvas 高度
document . body . append(canvasEl);// 将创立的 canvas 画布增加到页面的 body 元素下。
// 接下来须要判断浏览器对 WebGL 的兼容性。如果浏览器不反对 WebGL,那么咱们就不须要持续了。
如果 (!canvasEl.getContext(“webgl”) &&!canvasel . get context(” experimental-web GL “){
alert(“ 您的浏览器不反对 web GL “);
返回;
}
// 如果浏览器反对 Webgl,那么咱们将获取 Webgl 的 context 对象,并将其复制到变量 GL 中。
const context =(canvasel . get context(” web GL “))
?canvasEl.getContext(“webgl “)
:get context(” experimental-web GL “);
/*
设置 viewport context.viewport (x,y,width,height);
x: 用于设置视口左下角的程度坐标。默认值:0
y: 用于设置视口左下角的垂直坐标。默认值:0
宽度: 用于设置视口的宽度。默认值: 画布宽度
高度: 用于设置视口的高度。默认值: 画布的高度
当您第一次创立 WebGL 上下文时,视口大小与画布大小相匹配。然而,如果再次更改 canvas 的大小,须要通知 WebGL context 设置一个新的 viewport,所以此处能够省略这行代码,作为第一次创立它。
*/
context.viewport(0,0,context.canvas.width,context . canvas . height);
返回上下文;
}
复制代码
画布筹备好了,下一步是画三角形。就像咱们平时画画一样,须要筹备画三角形所需的顶点,也就是顶点着色器,以及对应的填充色彩,也就是面片着色器。
const GL = webglInit();
// 创立顶点着色器语法 gl.createShader(type)其中 type 是枚举值 gl 之一。顶点着色器或 gl。片段着色器
const v shader = GL . create shader(GL。顶点着色器)
// 编写顶点着色器的 GLSL 代码语法 gl.shaderSource(shader,source);shader- 用于设置程序代码的 webglShader (shader 对象) 源 - 蕴含 GLSL 程序代码的字符串
gl.shaderSource(vShader,
属性 vec4 v _ position
void main() {
gl Position = v position// 设置顶点地位
}
`)
Gl.compileShader(vShader) // 编译着色器代码
const f shader = GL . create shader(GL。片段_着色器)
gl.shaderSource(fShader,’ s
精细两头浮动;
对立 vec4 f _ color
void main() {
gl FragColor = f color// 设置单元格色彩。
}
`)// 编写片段着色器代码
Gl.compileShader(fShader) // 编译着色器代码
复制代码
咱们曾经实现了顶点着色器和片段着色器的配置,做好了渲染前的所有筹备工作。接下来,咱们须要创立一个程序来连贯咱们的顶点着色器和片段着色器,以实现最终的三角形渲染。// 创立一个程序来连贯顶点着色器和片段着色器。const program = gl.createProgram()
Gl.attachshader (program,v shader)// 增加顶点着色器
Gl.attachshader (program,f shader)// 增加片段着色器
Gl.linkProgram(program) // 连贯程序中的着色器。Gl.useProgram(program) // 通知 WebGL 应用这个程序进行渲染
const color = GL . getuniformlocation(program,'f_color')
// 获取 f_color 变量的地位
Gl.unifor4F (color,0.93,0,0.56,1)// 设置其值
const position = GL . getattributelocation(program,'v_position')
// 获取 v_position 的地位
const pBuffer = gl.createBuffer()
// 创立一个顶点缓冲区对象并返回其 id,用来放三角形顶点数据,bindBuffer(gl。ARRAY_BUFFER,pBuffer)
// 将此顶点缓冲区对象绑定到 gl。数组缓冲区
//GL 上的后续操作。ARRAY_BUFFER 将被映射到这个缓存。gl.bufferData(gl。ARRAY_BUFFER,new Float32Array([
0, 0.5,
0.5, 0,
-0.5, -0.5
]),// 三角形的三个顶点
// 因为数据会送到 GPU,所以为了节俭数据解析,这里用 Float32Array 间接传递数据。Gl。STATIC_DRAW // 示意缓冲区的内容不会频繁扭转。)
// 将顶点数据增加到新创建的缓存对象中
GL . vertexattributepointer(// 通知 OpenGL 如何从缓冲区获取数据
地位,// 顶点属性的索引
2,// 组件的数量,必须是 1,2,3 或 4。咱们只提供 X 和 y。Gl。FLOAT,// 每个元素的数据类型
True,// 是否规格化到特定范畴,浮点型数据的设置有效。0,stride step 数组中一行的长度,0 示意数据严密,没有空隙。让 OpenGL 决定具体的步长。0 // offset 字节偏移量,它必须是类型的字节长度的倍数。)
GL . enablevertexattribarray(position);// 关上属性变量 amount,以便顶点着色器能够拜访缓冲区数据
Gl.clearColor(0,1,1,1) // 设置色彩缓冲区清空时的色彩值。GL . Clear(GL . color _ buffer _ bit)// 革除色彩缓冲区,即革除画布。// 语法 gl.drawArrays(mode,first,count);模式 - 首先指定如何绘制图元 - 指定从哪个点开始绘制计数 - 指定要绘制多少个点。gl.drawArrays(gl。三角形,0,3)
复制代码
用 HTML 文件运行上述代码后,咱们能够在网页中看到如图所示的三角形,三角形大小是依据浏览器窗口大小自适应的。
能够看到,咱们仅仅画了一个简略的三角形,就写出了一长串 JS 代码。如果真的用原生的 WebGL API 写一个动静的 3D 交互网页,开发成本是极其低廉的。WebGL
原生 API 开发的毛病
下面这个 native WebGL API 绘制三角形的例子充沛向咱们展现了应用 native WebGL API 开发 3D 交互式网页存在的问题。尽管原生 WebGL API 能够满足任何场景的开发需要,然而其开发和学习老本极其低廉。对于 WebGL 的初学者来说是极其不敌对的,而且咱们须要配置顶点着色器来计算绘制顶点的地位,这须要开发者有肯定的数学根底来相熟矩阵运算,以及空间几何的概念来相熟 3D 物体的空间散布。灯光、纹理等的设计。场景的色调配置也须要咱们本人的见解。所以为了升高初学者的难度,上面我就介绍一些 WebGL 开发的罕用框架。
WebGL 开发的几种框架
三. js
Three.js 是 WebGL 的综合库,利用宽泛。美中不足的是 Three.js 库中没有全面具体的官网文档,对用户不是特地敌对。
铯. js
铯. js 是一个专门用于 3D 地图开发的 WebGL 库。它领有欠缺的 3D 地图开发 API,对于须要开发 3D 地图的开发者来说是个不错的抉择,然而对于其余场景的利用开发不是很全面。
巴比伦. js
Babylon.js 是国外宽泛应用的 WebGL 库。有趣味的小伙伴能够本人理解一下,这里就不具体介绍了。
Three.js
是在浏览器中运行的 3D 引擎。你能够用它来创立各种 3D 场景。同时 Three.js 也是一个综合性的 WebGL 库。如果须要开发 3D 地图网页,能够应用铯. js,这是一个专门用于地图开发的 WebGL 库。Babylon.js 是国外比拟风行的 WebGL 库。
基于 Three.js 绘制旋转立方体
用 Three.js 画旋转立方体的第一步和原生 WebGl 一样。第一步是筹备 Three.js 运行的环境。// 创立渲染器变量来存储渲染器对象
var 渲染器;initthree 函数用于初始化 Three.js 运行所需的环境。函数 initThree() {
// 就像构建原生 WebGL 环境的过程一样,Three.js 也须要先设置 canvas 元素的大小。width = document . getelementbyid('canvas-frame')。clientWidth// 将 width 属性设置为浏览器窗口的宽度。height = document . getelementbyid('canvas-frame')。客户端高度;// 将 height 属性设置为浏览器窗口高度。// 创立新的 WebGL 渲染器,并将其赋给渲染器变量
渲染器 = 新三。WebGLRenderer({抗锯齿: 正确});
// 将画布大小设置为浏览器窗口大小
renderer.setSize(宽度,高度);// 将画布元素装载到页面上
document . getelementbyid('canvas-frame')。appendChild(renderer . DOM element);// 将空画布的色彩设置为红色
renderer . setclearcolor(0x ffffff,1.0);}