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);
}