WebGL
文章平均质量分 91
WebGL是一种能够在Web浏览器中进行高性能3D图形渲染的JavaScript API。它是基于OpenGL标准的一个子集,并通过在浏览器中嵌入3D图形元素,使得开发者能够在Web平台上创建交互式的三维图形应用程序。WebGL利用计算机的图形处理单元(GPU)来加速图形渲染,因此能够在浏览器中呈现
山楂树の
Always believe that something wonderful is about to happen.
展开
-
WebGL 世界坐标系和本地坐标系
本地坐标系:当我们创建三维模型时,需要知道原点(0.0,0.0,0.0)在何处。你可以自由选择原点的位置,所以三维模型的建立就比较容易,或者说很容易确定三维模型在场景中的位置。之前我们创建的立方体,原点就在立方体的中心。球状物体如太阳和月亮等,通常也将原点设置在球心。另一方面,大部分上图所示的游戏角色模型,其原点大部分都是位于脚部,Y轴垂直向上穿过身体的中线。这样,如果我们将角色放置在y坐标为0的位置(也就是地面),角色看上去就像站立在地面上一样——既没有悬浮在空中,也没有沉入地面以下。这时,如果我们沿原创 2023-10-17 20:03:39 · 303 阅读 · 0 评论 -
WebGL 响应上下文丢失解决方案
WebGL使用了计算机的图形硬件,而这部分资源是被操作系统管理,由包括浏览器在内的多个应用程序共享。在某些特殊情况下,如另一个程序接管了图形硬件,或者操作系统进入休眠,浏览器就会失去使用这些资源的权利,并导致存储在硬件中的数据丢失。在这种情况下,WebGL绘图上下文就会丢失。比如,如果你正在一台笔记本电脑或智能手机上运行WebGL程序,如下图(左)所示,然后使其进入休眠状态,通常此时浏览器的控制台会显示一条错误新消息。当你将电脑或手机重新唤醒后,操作系统确实回到了休眠前的状态,但是浏览器中运行的WebGL程原创 2023-10-05 15:00:04 · 1530 阅读 · 1 评论 -
WebGL 渲染三维图形作为纹理贴到另一个三维物体表面
WebGL简单而又强大的技术是,使用WebGL渲染三维图形,然后将渲染结果作为纹理贴到另一个三维物体上去。实际上,把渲染结果作为纹理使用,就是动态地生成图像,而不是向服务器请求加载外部图像。在纹理图像被贴上图形之前,我们还可以对其做一些额外的处理,比如生成如动态模糊或景深效果。本文将创建了一个新的示例程序FramebufferObject,将一个旋转的立方体作为纹理贴在一个矩形上,如下图所示。原创 2023-09-28 21:17:34 · 417 阅读 · 0 评论 -
WebGL 切换着色器
WebGL中,如果一个着色器就能绘制出场景中所有的物体,那就没有问题。然而事实是,对不同的物体经常需要使用不同的着色器来绘制,每个着色器中可能有非常复杂的逻辑以实现各种不同的效果。我们可以准备多个着色器,然后根据需要来切换使用它们。本文的示例程序ProgramObject就使用了两个着色器绘制了两个立方体,一个是纯色的,另一个贴有纹理。下图显示了程序的运行效果。原创 2023-09-27 17:45:46 · 1399 阅读 · 1 评论 -
WebGL实现透明物体(α混合)
颜色中的α分量(即RGBA中的A)控制着颜色的透明度。如果一个物体颜色的α分量值为0.5,该物体就是半透明的,透过它可以看到该物体背后的其他物体。如果一个物体颜色的α分量值为0,那么它就是完全透明的,我们将完全看不到它。在本文的示例程序中,随着α分量的降低,整个绘图区域会逐渐成为白色,因为在默认情况下,α混合不仅影响绘制的物体,也会影响背景色,最后你看到的白色实际上是<canvas>后空白的网页。原创 2023-09-27 16:44:38 · 336 阅读 · 0 评论 -
WebGL绘制圆形的点
为了绘制一个圆点,我们需要将原先的方点“削”成圆形的。我们知道,顶点着色器和片元着色器之间发生了光栅化过程,一个顶点被光栅化为了多个片元,每一个片元都会经过片元着色器的处理。如果直接进行绘制,画出的就是方形的点;而如果在片元着色器中稍作改动,只绘制圆圈以内的片元,这样就可以绘制出圆形的点了,为了将矩形削成圆形,需要知道每个片元在光栅化过程中的坐标。之前的程序在片元着色器中通过内置变量gl_FragCoord来访问片元的坐标。实际上,片元着色器还提供了另一个内置变量gl_PointCoord,如下表所示。这个原创 2023-09-25 22:45:56 · 252 阅读 · 0 评论 -
WebGL雾化
在三维图形学中,术语雾化(fog)用来描述远处的物体看上去较为模糊的现象。实现雾化的方式有很多种,这里使用最简单的一种: 线性雾化(linear fog)。在线性雾化中,某一点的雾化程度取决于它与视点之间的距离,距离越远雾化程度越高。线性雾化有起点和终点,起点表示开始雾化之处,终点表示完全雾化之处,两点之间某一点的雾化程度与该点与视点的距离呈线性关系。注意,比终点更远的点完全雾化了,即完全看不见了。某一点雾化的程度可以被定义为雾化因子(fog factor),并在线性雾化公式中被计算出来,如下式所示。原创 2023-09-24 22:08:28 · 207 阅读 · 1 评论 -
WebGL 常用术语整理
A α混合(alpha blending):使用α值(RGBA中的“A”)混合两个以上物体的颜色的过程。α值(alpha value):用来表示物体透明度(0.0表示完全透明,1.0表示完全不透明)的值。α混合需要使用α值。环境光(ambient light):无方向的光,以相同的强度从所有的方向照射在物体上。连接(attach):在两个已存在的对象间建立联系的过程,注意与绑定比较。attribute变量(attribute variable):向顶点着色器传入数据的变量。原创 2023-09-21 23:57:53 · 314 阅读 · 1 评论 -
【三维世界】高性能图形渲染技术——WebGL你又了解多少?
WebGL,是一项用来在网页上绘制和渲染复杂三维图形(3D图形),并允许用户与之进行交互的技术。传统意义上来说,只有高配置的计算机或专用的游戏机才能渲染三维图形。而现在,随着个人计算机和浏览器的性能越来越强,使用便捷通用的Web技术创建渲染三维图形已经成为可能。WebGL技术结合了HTML5和JavaScript,允许开发者在网页(Web页面)上创建和渲染三维图形。这项技术将在开发下一代易用直观用户界面和生产互联网内容上发挥重要作用,下图中展示了几个例子。可以预见,在接下来的若干年中,WebGL技术将在传统原创 2023-09-21 23:11:49 · 470 阅读 · 0 评论 -
WebGL HUD(平视显示器)
WebGL中在三维场景上叠加文本或二维图形信息,以达到HUD的效果,具体实现过程如下:1.在HTML文件中,为WebGL绘制的三维图形准备一个<canvas>,同时为二维的HUD信息再准备一个<canvas>。令这两个<canvas>重叠放置,并让HUD的<canvas>叠在上面。2.在前一个<canvas>上使用WebGL API绘制三维场景。3.在后一个<canvas>上使用canvas 2D API绘制HUD信息。原创 2023-09-21 22:42:39 · 534 阅读 · 0 评论 -
WebGL 选中一个表面
在WebGL中,gl.readPixels()函数用于从帧缓冲区中读取像素数据(而非颜色缓冲区中)。该函数的第六个参数用于指定返回的像素数据的数据类型。当将第六个参数设置为gl.UNSIGNED_BYTE时,表示希望返回的像素数据以无符号字节的形式表示。每个像素将用一个8位无符号整数(即一个字节)来表示。使用gl.UNSIGNED_BYTE可以获得每个像素的红、绿、蓝和透明度通道的值(RGB或RGBA)的整数表示,取值范围在0到255之间。(见gl.readPixels()原创 2023-09-21 22:22:58 · 260 阅读 · 0 评论 -
WebGL 选中物体
有些三维应用程序需要允许用户能够交互地操纵三维物体,要这样做首先就得允许用户选中某个物体。对物体进行选中操作的用处很广泛。比如,让用户选中三维用户界面上的一个按钮,或者让用户选中三维场景中的多张照片中的某一张,这些动作都具有实际意义。选中三维物体比选中二维物体更加复杂,因为我们需要更多的数学过程来计算鼠标是否悬浮在某个图形上。但是,示例程序PickObject使用了一个简单的技巧解决了这一问题。在本例中,用户可以点击正在旋转的立方体,如果用户点击到了立方体,就显示一则消息,如下图所示。原创 2023-09-21 22:16:00 · 284 阅读 · 0 评论 -
WebGL 用鼠标控制物体旋转
有时候,WebGL程序需要让用户通过鼠标操作三维物体。这一节来分析示例程序,该程序允许用户通过拖动(即按住左键移动)鼠标旋转三维物体。为了简单,示例程序中的三维物体是一个立方体,但拖曳鼠标旋转物体的方法却适用于所有物体。下图显示了程序的运行效果,立方体上贴有纹理图像。原创 2023-09-21 21:20:28 · 819 阅读 · 0 评论 -
WebGL 初始化着色器
1. 创建着色器对象(gl.createShader())。2. 向着色器对象中填充着色器程序的源代码(gl.shaderSource())。3. 编译着色器(gl.compileShader())。4. 创建程序对象(gl.createProgram())。5..为程序对象分配着色器(gl.attachShader())。6. 连接程序对象(gl.linkProgram())。7. 使用程序对象(gl.useProgram())。虽然每一步看上去都比较简单,但是放在一起显得复杂了,我们将逐条讨论。首先,你原创 2023-09-21 20:44:19 · 445 阅读 · 0 评论 -
WebGL层次模型——多节点模型
本文将绘制一个具有多个关节的完整的机器人手臂,包括基座(base)、上臂(arm1)、前臂(arm2)、手掌(palm)、两根手指(finger1 & finger2),全部可以通过键盘来控制。arm1和arm2的连接关节joint1位于arm1顶部,arm2和palm的连接关节joint2位于arm2顶部,finger1和finger2位于palm一端,如下图所示。原创 2023-09-20 18:12:13 · 251 阅读 · 2 评论 -
WebGL层次模型——单节点模型
绘制由多个小部件组成的复杂模型,最关键的问题是如何处理模型的整体移动,以及各个小部件间的相对移动。首先,考虑一下人类的手臂:从肩部到指尖,包括上臂(肘以上)、前臂(肘以下)、手掌和手指,如下图所示。手臂的每个部分可以围绕关节运动,如上图所示:● 上臂可以绕肩关节旋转运动,并带动前臂、手掌和手指一起运动。● 前臂可以绕肘关节运动,并带动手掌和手指一起运动,但不影响上臂。● 手掌绕腕关节运动,并带动手指一起运动,但不影响上臂和前臂。● 手指运动不影响上臂、前臂和手掌。原创 2023-09-19 19:24:04 · 153 阅读 · 0 评论 -
WebGL 计算点光源下的漫反射光颜色
与平行光相比,点光源光发出的光,在三维空间的不同位置上其方向也不同,如下图所示。所以,在对点光源光下的物体进行着色时,需要在每个入射点计算点光源光在该处的方向。点光源光的方向随位置变化示例程序是示例程序的点光源光版本,显示了一个点光源下的红色立方体。立方体表面仍然是漫反射,环境光保持不变,程序的效果如下图所示。原创 2023-09-18 20:40:43 · 235 阅读 · 0 评论 -
WebGL 根据模型矩阵的逆转置矩阵计算运动物体的光照效果
在WebGL中,物体的运动会改变每个表面的法向量,从而导致光照效果发生变化。要计算变换后的法向量:用法向量乘以模型矩阵的逆转置矩阵,就可以求得变换后的法向量。求逆转值矩阵的两个步骤:1.求原矩阵的逆矩阵。2.将上一步求得的逆矩阵进行转置。Matrix4对象WebGL矩阵变换库_山楂树の的博客-CSDN博客提供了便捷的方法来完成上述任务,如下所示。原创 2023-09-17 17:36:44 · 551 阅读 · 0 评论 -
WebGL 计算平行光、环境光下的漫反射光颜色
漫反射是针对平行光或点光源而言的。在漫反射中,反射光的颜色取决于入射光的颜色、表面的基底色、入射光与表面形成的入射角。我们将入射角定义为入射光与表面的法线形成的夹角,并用θ表示,那么漫反射光的颜色可以根据下式计算得到:原创 2023-09-17 16:51:04 · 543 阅读 · 0 评论 -
WebGL 从0到1绘制一个立方体
我们来绘制如下图所示的立方体(图右侧显示了立方体每个顶点的坐标),其8个顶点的颜色分别为白色、品红色(亮紫色)、红色、黄色、绿色、青色(蓝绿色)、蓝色、黑色。你也许知道,为每个顶点定义颜色后,表面上的颜色会根据顶点颜色内插出来,形成一种光滑的渐变效果(“色体”,相当于二维的“色轮”)。绘制三角形,我们都是调用gl.drawArrays()方法来进行绘制操作的。考虑一下,如何用该函数绘制出一个立方体呢。我们只能使用gl.TRIANGLES、gl.TRIANGLE_STRIP或者gl.TRIANGLE_FAN模原创 2023-09-16 15:22:18 · 391 阅读 · 0 评论 -
WebGL 正确处理对象前后的关系——隐藏面消除(深度测试)/ 深度冲突
WebGL在默认情况下会按照缓冲区中的顺序绘制图形,而且后绘制的图形覆盖先绘制的图形,因为这样做很高效。但是如果,比如说你希望不断移动视点,从不同的角度看物体,那么你不可能事先决定对象出现的顺序。为了解决这个问题,WebGL提供了隐藏面消除(hidden surface removal)功能。这个功能会帮助我们消除那些被遮挡的表面(隐藏面),你可以放心地绘制场景而不必顾及各物体在缓冲区中的顺序,因为那些远处的物体会自动被近处的物体挡住,不会被绘制出来。原创 2023-09-14 23:39:18 · 288 阅读 · 0 评论 -
WebGL模型视图投影矩阵
在WebGL中,你可以使用投影矩阵、视图矩阵、模型矩阵这3种矩阵计算出最终的顶点坐标(即顶点在规范立方体中的坐标)。如果投影矩阵为单位阵,那么等式3与等式1就完全相同了;同样,如果模型矩阵为单位阵,那么等式3与等式2就完全相同了。单位阵就像乘法中的1一样,它乘以任意一个矩阵,或者任意一个矩阵乘以它,得到的结果还是这个矩阵(程序中不设置投影矩阵所需的任一参数,默认参数所计算得到的矩阵可理解为1)。原创 2023-09-14 21:15:56 · 285 阅读 · 0 评论 -
WebGL透视投影
在透视投影下,产生的三维场景看上去更是有深度感,更加自然,因为我们平时观察真实世界用的也是透视投影。在大多数情况下,比如三维射击类游戏中,我们都应当采用透视投影。在下图的场景中,道路两边都有成排的树木。树应该都是差不多高的,但是在照片上,越远的树看上去越矮。同样,道路尽头的建筑看上去比近处的树矮,但实际上那座建筑比树高很多。这种“远处的东西看上去小”的效果赋予了照片深度感,或称透视感。我们的眼睛就是这样观察世界的。有趣的是,孩童的绘画往往会忽视这一点。在正射投影的可视空间中,不管三角形与视点的距离是远是近,原创 2023-09-14 16:45:47 · 328 阅读 · 0 评论 -
WebGL正射投影
正射投影可以方便地比较场景中物体(比如两个原子的模型)的大小,这是因为物体看上去的大小与其所在的位置没有关系。在建筑平面图等技术绘图的相关场合,应当使用这种投影。正射投影盒状可视空间的形状如下图所示。可视空间由前后两个矩形表面确定,分别称近裁界面(near clipping plane)和远裁截面(far clipping plane),前者的四个顶点为(right,top,-near),(-left,top,-near),(-left,-bottom,-near),(right,-bottom,-near原创 2023-09-13 19:13:42 · 195 阅读 · 3 评论 -
WebGL 视图矩阵、模型视图矩阵
“根据自定义的观察者状态,绘制观察者看到的景象”与“使用默认的观察状态,但是对三维对象进行平移、旋转等变换,再绘制观察者看到的景象”,这两种行为是等价的。不论视图怎样变化,无疑就是旋转、平移等操作,最终本质上都是对物体进行相反方向的旋转平移(默认的视角)视点移动的方向与被观察对象(也就是整个世界)移动的方向正好相反。对于视点的旋转,也可以采用类似的方式。 如下式 <模型视图矩阵>=<视图矩阵>×<模型矩阵>原创 2023-09-11 23:59:26 · 426 阅读 · 0 评论 -
WebGL 同时使用多幅纹理
WebGL可以同时处理多幅纹理,纹理单元就是为了这个目的而设计的。首先,让我们来看一下片元着色器,本例用到了两幅纹理,那么就需要两个定义uniform变量,在片元着色器的main()函数中,我们从两个纹理中取出颜色,分别存储在变量color0和color1使用两个纹素来计算最终的片元颜色(gl_FragColor)有多种可能的方法。示例程序使用的是颜色矢量的分量乘法——两个矢量中对应的分量相乘作为新矢量的分量,如下图所示。这很好理解。在GLSL ES中,只需要将两个vec4变量简单相乘一下就可以达到目的。原创 2023-09-09 15:24:03 · 304 阅读 · 0 评论 -
WebGL 纹理——在矩形表面贴上图像
WebGL要进行纹理映射,需遵循以下四步:1. 准备好映射到几何图形上的纹理图像。2.为几何图形配置纹理映射方式。3.加载纹理图像,对其进行一些配置,以在WebGL中使用它。4.在片元着色器中将相应的纹素从纹理中抽取出来,并将纹素的颜色赋给片元。接下来,我们来仔细研究上述第1步到第4步。第1步中准备的纹理图像,可以是浏览器支持的任意格式的图像。你可以使用任何照片第2步指定映射方式,就是确定“几何图形的某个片元”的颜色如何取决于“纹理图像中哪个(或哪几个)像素”的问题(即前者到后者的映原创 2023-09-06 23:59:25 · 464 阅读 · 1 评论 -
WebGL Varing变量的作用和内插过程,及执行Varing时涉及的图形装配、光栅化、颜色插值、片元着色器执行机制等详解
在 WebGL 或 OpenGL 中,“varying” 是一种用于在顶点着色器和片元着色器之间传递数据的特殊类型的变量。它允许在顶点着色器对数据进行处理后,在片元着色器中使用该处理后的数据进行进一步计算。顶点着色器和片元着色器之间的过程非常重要。光栅化也是三维图形学的关键技术之一,它负责将矢量的几何图形转变为栅格化的片元(像素)。图形被转化为片元之后,我们就可以在片元着色器内做更多的事情,如为每个片元指定不同的颜色。颜色可以内插出来,也可以直接编程指定。原创 2023-08-31 23:44:05 · 651 阅读 · 0 评论 -
WebGL 同一缓冲区多种数据传入顶点着色器 gl.vertexAttribPointer()的步进和偏移参数
参数stride表示,在缓冲区对象中,单个顶点的所有数据(这里,就是顶点的坐标和大小)的字节数,也就是相邻两个顶点间的距离,即步进参数。参数offset表示当前考虑的数据项距离首个元素的距离,即偏移参数。在verticesSizes数组中,顶点的坐标数据是放在最前面的,所以应当为0。因此,我们调用gl.vertexAttribArray()函数时,如下所示传入stride参数和offset参数原创 2023-08-31 22:25:40 · 493 阅读 · 0 评论 -
WebGL模型矩阵
在JavaScript中计算<旋转矩阵>×<平移矩阵>,然后将得到的矩阵传入顶点着色器。像这样,我们就可以把多个变换复合起来了。一个模型可能经过了多次变换,将这些变换全部复合成一个等效的变换,就得到了模型变换(model transformation),或称建模变换(modeling transformation),相应地,模型变换的矩阵称为模型矩阵(model matrix)。原创 2023-08-30 00:07:28 · 572 阅读 · 0 评论 -
WebGL矩阵变换库
Matrix4对象有两种方法:一种方法的名称中含有前缀set,另一种则不含。包含set前缀的方法会根据参数计算出变换矩阵,然后将变换矩阵写入到自身中;而不含set前缀的方法,会先根据参数计算出变换矩阵,然后将自身与刚刚计算得到的变换矩阵相乘,然后把最终得到的结果再写入到Matrix4对象中。原创 2023-08-30 00:06:19 · 371 阅读 · 0 评论 -
WebGL矩阵变换
对于简单的变换,你可以使用数学表达式来实现。但是当情形逐渐变得复杂时,你很快就会发现利用表达式运算实际上相当繁琐。比如,下图显示了一个“旋转后平移”的过程,如果使用数学表达式,我们就需要两种变换的等式叠加,获得一个新的等式,然后在顶点着色器中实现。原创 2023-08-27 20:59:29 · 510 阅读 · 0 评论 -
WebGL绘制函数gl.drawArrays
WebGL方法gl.drawArrays()既强大又灵活,通过给第1个参数mode指定不同的值,在这个参数上指定不同的值,我们可以按照不同的规则绘制图形。下图中的7种基本图形是WebGL可以直接绘制的图形原创 2023-08-26 16:52:32 · 286 阅读 · 0 评论 -
WebGL 缓冲区对象介绍,创建并使用缓冲区,使用缓冲区对象向顶点着色器传入多个顶点数据的所有步骤
WebGL提供了一种很方便的机制,即缓冲区对象(buffer object),它可以一次性地向着色器传入多个顶点的数据。缓冲区对象是WebGL系统中的一块内存区域,我们可以一次性地向缓冲区对象中填充大量的顶点数据,然后将这些数据保存在其中,供顶点着色器使用。在进一步解释缓冲区对象前,让我们先浏览一下下面的示例程序函数initVertexBuffers()的任务是创建顶点缓冲区对象,并将多个顶点的数据保存在缓冲区中,然后将缓冲区传给顶点着色器。函数的返回值是待绘制顶点的数量,保存在变量n中。原创 2023-08-24 23:57:21 · 644 阅读 · 0 评论 -
WebGL uniform变量、gl.getUniformLocation、gl.uniform4f及其同族函数相关介绍
着色器将 uniform 变量 u_FragColor 赋值给 gl_FragColor,后者直接决定点的颜色,向 uniform 变量传数据的方式与向 attribute 变量传数据相似:首先获取变量的存储地址,然后在JS程序中按照地址将数据传递过去。原创 2023-08-23 23:16:40 · 514 阅读 · 0 评论 -
WebGL 存储限定符attribute、gl.getAttribLocation、gl.vertexAttrib3f及其同族函数和矢量版本的介绍
在WebGL系统中建立了顶点着色器,WebGL就会对着色器进行解析,辨识出着色器具有的attribute变量,每个变量都具有一个存储地址,以便通过存储地址向变量传输数据。比如,当你想要向顶点着色器的a_Position变量传输数据时,首先需要向WebGL系统请求该变量的存储地址。我们使用gl.getAttribLocation()来获取attribute变量的地址。原创 2023-08-17 23:24:44 · 479 阅读 · 0 评论 -
Three.js制作物体粒子爆炸特效,Shader实现
【代码】Three.js制作物体粒子爆炸特效,Shader实现。操作用于传递到每个物体的着色器材质ShaderMaterial中的顶点着色器配置信息,遍历物体顶点组,得到每个每个物体的顶点信息对象points,设置所有物体所有顶点的xyz移动范围为-10到10,将坐标信息设置到每个物体缓冲区对象中,由顶点着色器接收原创 2023-05-13 13:49:16 · 851 阅读 · 0 评论