WebGL透明度与α融合

WebGL教程(电子书)
本文是WebGL电子书的1.15节内容

半透明三角形叠加.html源码效果如下如图所示。

渲染管线之融合

GPU的渲染管线有各种功能单元,比如前面讲到的深度测试侧单元,通过执行gl.enable(gl.DEPTH_TEST)语句可以开启GPU渲染管线的深度测试单元, 同样更改WebGL API gl.enable()的参数也可以指定开启其它的功能模块,参数gl.BLEND就表示渲染管线的α融合单元,α融合的英文是alpha blending,RGBA中透明度分量A就是alpha的首字母, 英文单词alpha是对希腊字符α的称呼,中文音译为“阿法”,RGBA也可以写为RGBα。通过颜色的融合技术可以模拟很多现象,比如实现生活中半透明的效果,模拟玻璃材质都需要用到GPU渲染管线的α融合功能单元。

WebGL API gl.enable()参数

表格中列举出了WebGL API gl.enable()的参数对应的功能模块,这些功能模块都处于渲染管线这条流水线上的不同位置,相互配合完成工作,深度检测、α融合都是对RGBA像素相关的数据进行处理, 也就是说渲染管线上的这些测试单元都位于顶点着色器、片元着色器的后面,用来处理经过顶点着色器、光栅器、片元着色器处理后的相关数据。

参数 功能
gl.DEPTH_TEST 深度测试,消除看不到隐藏面
gl.BLEND α融合,实现颜色融合叠加
gl.POLYGON_OFFSET_FILL 多边形偏移,解决深度冲突

半透明三角形叠加

下面的代码绘制了三个颜色分别为红、绿、蓝的三角面,它们的透明度都是0.5,使用浏览器测试你可以看到颜色相互叠加融合的效果,就相当于不同颜色的半透明玻璃多层叠加起来呈现的视觉效果。

所谓融合,就是相同x、y坐标值的源颜色与目标颜色混合后覆盖目标颜色。以本程序为例,先后绘制了三个三角面,这些三角面的顶点是有顺序的,顶点被处理后得到的三角面RGB值绘制到颜色缓冲区中也是有顺序的, 后绘制的三角面像素就是源颜色,先绘制的三角面像素就是目标颜色,先绘制的颜色是被覆盖的目标,这正是名词目标颜色的来源。你可以这么理解,先绘制的三角面是玻璃后面的物体,后绘制的三角面是物体前面的玻璃, 物体会被先绘制绘制出来,它的像素值存在颜色缓冲区中,当绘制玻璃的时候,如果你开启了α融合功能,系统就会呈现出玻璃和物体的综合视觉效果,两者的颜色融为一体。没有绝对的源颜色和目标颜色,都是相对的,第二个绘制的三角面的像素 相对第一个绘制的相当于源颜色,二相对地单个绘制的三角面的像素是目标颜色,将要被覆盖的颜色。

开启、设置α融合

/*** 渲染管线α融合功能单元配置**/
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);

代码gl.enable(gl.BLEND);表示开启GPU渲染管线的α融合功能,比如源颜色像素值是(R1,G1,B1,A1),目标颜色像素值是(R2,G2,B2,A2),融合后的像素值计算方法如下:

R3 = R1 x A1 + R2 x (1 - A1)

R3 = G1 x A1 + G2 x (1 - A1)

R3 = B1 x A1 + B2 x (1 - A1)

可以利用一些极值测试上面的计算公式,比如后绘制的面不透明,相当于A1等于1,代入上面的公式1 - A1就表示0,也就是说先绘制面的像素值被完全覆盖;如果后绘制的面完全透明,A1是0,那么R1 x A1结果就是0, 也就是说绘制的面无论它是什么颜色,融合后的像素值就是后面物体的像素,也就是说后绘制的三角面你看不到它的存在。这时候你可能会想到生活中玻璃,它也是透明的,但是能够看到,其实玻璃的透明度并不是100%, 光线照射到玻璃上一部分光线会透射穿过玻璃,同时一部分光线会反射到眼睛里面,也就是说实际进行材质建模的时候,玻璃的透明度可以接近0,但不能为0,生活中的玻璃有各种颜色,最常见的是无色, 这里的无色描述并不准确,实际上还是有一定颜色的,只是相对透明,体现不出来,在与玻璃后面的场景融合的时候被稀释,普通的无色玻璃RGB值接近0,但不能为0,否则计算机模拟计算的时候,你是看不到的, 你可以把案例程序中红色三角面的顶点颜色数据透明度分量A设置为0,刷新浏览器就看不到这个三角形的存在,虽然它的R分量是1,但是体现不出来。

gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);代码定义就是源颜色和目标颜色融合的计算方法,计算方法就是上面公式的颜色融合算法,颜色融合的算法除了上面列举的还有其他的方式,只需要更改融合函数blendFunc()的两个参数,就可以设置不同的颜色融合算法。

第一个参数gl.SRC_ALPHA表示的就是前面像素透明度分量A1的值,第二个参数gl.ONE_MINUS_SRC_ALPHA表示1-A1。A1表示后绘制三角面像素的透明度,表示后绘制的三角面

gl.enable()的参数除了gl.SRC_ALPHAgl.ONE_MINUS_SRC_ALPHA,还有其它的值,实际计算的时候并不一定把靠前的像素的透明度作为RGB分量乘法计算的系数, 也可能是后面像素的透明度,也可能是RGB三原色分量,这时候你可能会觉得这是不是违反常理,其实并不是如此,因为颜色的融合不单单包括半透明材质的模拟,还有其它的使用情形, 下面列表中,含有s的表示后绘制的三角面的RGBA值,也就是源颜色,含有d的表示先绘制的三角面的RGBA值,也就是目标颜色。

gl.blendFunc()的第一个参数是源颜色的系数,第二个参数是目标颜色的系数,两组像素值乘以各自系数后然后相加得到融合后的像素值,覆盖原来的像素值,注意覆盖的时候是覆盖x、y坐标相同的像素。

R3 = R1 x 参数1 + R2 x 参数2

R3 = G1 x 参数1 + G2 x 参数2

R3 = B1 x 参数1 + B2 x 参数2

Header One Header Two
Item One Item Two
参数 红色R分量系数 绿色G分量系数 蓝色B分量系数
gl.ZERO 0 0 0
gl.ONE 1 1 1
gl.SRC_COLOR Rs Gs Bs
gl.ONE_MINUS_SRC_COLOR 1 – Rs 1 – Gs 1 – Bs
gl.DST_COLOR Rd Gd Bd
gl.ONE_MINUS_DST_COLOR 1 - Rd 1 - Gd 1 - Bd
gl.SRC_ALPHA As As As
gl.ONE_MINUS_SRC_ALPHA 1 - As 1 - As 1 - As
gl.DST_ALPHA Ad Ad Ad
gl.ONE_MINUS_DST_ALPHA 1 - Ad 1 - Ad 1 - Ad
gl.SRC_ALPHA_SATURATE min(As, Ad) min(As, Ad) min(As, Ad)

顶点位置、颜色数据

下面设置了三个三角形的顶点坐标数据、顶点颜色数据,每个顶点都设置了透明度,这些顶点的透明度在顶点光栅化生成片元的过程中都会赋值给每个片元, 顶点颜色、顶点法向量可以进行插值计算,同样顶点的透明度也会进行插值计算,在通过片元着色器程序赋值给片元,最后在渲染管线α融合单元可以把透明度分量A作为系数对颜色执行乘法运算, 再执行加法运算实现两个具有前后叠加位置关系像素的融合。

可以更改一个顶点的透明度分量A的值为1,刷新浏览器你会看到一个渐变色的效果,也就是说一个三角面不同的位置的片元像素值实现了不同的透明度, 也就说明了透明度分量A和颜色值RGB三原色分量一样会进行插值计算。

/**创建顶点位置数据数组data,存储6个顶点创建顶点颜色数组colorData,存储6个顶点对应RGB颜色值**/
var data=new Float32Array([-0.5,0.5,0.5,0.5,0.5,-0.5,//红色三角形的三个顶点-0.7,0.3,0.3,0.3,0.3,-0.7,//绿色三角形的三个顶点-0.3,0.7,0.7,0.7,0.7,-0.3//蓝色三角形的三个顶点
]);
var colorData = new Float32Array([//红色顶点,透明度0.71,0,0,0.7,1,0,0,0.7,1,0,0,0.7,//绿色顶点,透明度0.70,1,0,0.7,0,1,0,0.7,0,1,0,0.7,//蓝色顶点,透明度0.70,0,1,0.7,0,0,1,0.7,0,0,1,0.7
]);

着色器获取缓冲区中数据的方式

顶点颜色数据每4个是一组,表示颜色值RGBA,相比前面的课程中多了一个透明度分量,gl.vertexAttribPointer()的第2个参数自然要更改为4,。

gl.vertexAttribPointer(a_color,4,gl.FLOAT,false,0,0);

颜色叠加顺序

本程序中执行绘制函数之前,没有设置深度测试,就不会考虑像素的Z值,绘制的三个三角面的像素会按照顶点的绘制顺序叠加在一起,后绘制的像素覆盖先绘制的像素,你可以把所有顶点的透明度分量更改为1表示不透明,就可以看到他们的叠加关系。

/**执行绘制命令**/
gl.drawArrays(gl.TRIANGLES,0,9);

WebGL透明度与α融合相关推荐

  1. unity Image/RawImage贴图透明度渐变/融合 正片叠底

    功能需求:UI边界太硬,需要做个渐变看起来更柔和. 最终效果:(UI上方透明度渐变) 正文开始: 方法一:通过获取 Image/RawImage UI顶点数据(color属性的Alpha)来处理.可参 ...

  2. WebGL视频教程-郭龙帮-专题视频课程

    WebGL视频教程-169人已学习 课程介绍         随着浏览器性能的提高,会有越来越多的3D应用云端化,学习WebGL技术将会越来越流行. 课程收益     适合没有任何图形学基础,甚至没有 ...

  3. webgl坐标转换_WebGL教程

    前言 通过WebGL做了很多项目,感觉有必要录制一套视频教程,所以在这里写一个录制大纲,大家也可以通过章节目录了解下WebGL的基本内容. 视频教程发布地址 Threejs引擎 Threejs是web ...

  4. WebGL教程(电子书)

    WebGL教程(电子书) 最近准备编写一本WebGL快速入门的电子书教程,电子书编写完整后,预览地址在我的个人技术博客,目前还在编写中,博客部署电子书之前,会把电子书已经写好的每一小节以文章的形式发布 ...

  5. Three开发笔记(二)

    文章目录 1. 学习使用Three.js 中的光源 THREE. AmbientLight THREE. Color THREE. PointLight THREE. SpotLight THREE. ...

  6. 《迅雷链精品课》第四课:区块链技术的发展趋势

    上一节课我们系统学习了目前主流的区块链项目的技术架构:思考我们在设计具体的业务架构时,需要决定什么业务应该上链,什么业务应该用链下服务处理:今天我们将深入了解区块链技术发展趋势.在区块链落地应用过程中 ...

  7. 外星世界,真实呈现,外星版Pokemon Go是如何做到的?

    背景介绍 基于Pokemon的故事背景的Pokemon Go在刚上线时,在全世界风靡一时.玩家可以通过智能手机在现实世界里发现宠物小精灵(宝可梦),进行抓捕和战斗.打开手机App, 通过摄像头画面就能 ...

  8. PIL:处理图像的好模块

    介绍 PIL是一个专门用来处理图像的模块,可以对图象进行各种各样的变换 打开一张图片 python from PIL import Image# 调用Image下的open方法,即可打开一张图片 # ...

  9. ArcGIS VS QGIS——两者之间的27点比较

    本文是笔者刚刚接触QGIS相关博客资源时找到的一篇文章,全文比较长,因此分成两篇发布.就内容而言不代表笔者观点,留待后续一一验证. QGIS和ArcGIS的比较 你也许伴随着ArcGIS或者QGIS而 ...

最新文章

  1. 【部署类】专题:消息队列MQ、进程守护Supervisor
  2. VMware安装Centos7桌面版超详细图文过程
  3. python划分有限元网格_有限元网格划分应该考虑些什么
  4. ImportError: No module named _sqlite3 报错解决方法
  5. asp.net机器人注册原理
  6. 数据结构:利用栈,将递归转换为非递归的方法
  7. GridView RowCommand事件中取得當前行
  8. echars显示折点数据_数据可视化的基础语法
  9. javascript判断是否手机设备+滑动事件
  10. Google Maps API 申请方式变更为APIs Console, android手机申请方式
  11. codeforces 776C Molly's Chemicals(连续子序列和为k的次方的个数)
  12. Windows 8实例教程系列 - 开篇
  13. Windows 8 Directx 开发学习笔记(九)材质定义及混合光照效果实现
  14. 华为鸿蒙系统老手机能用吗_华为发布鸿蒙2.0手机开发者测试版!华为老手机可申请公测...
  15. 关于拉格朗日对偶问题中对偶性的理解 (很有趣)
  16. 查看和修改mysql最大连接数
  17. java——7个小案例
  18. html---标题居中,背景图片
  19. OpenHarmony恢复启动子系统init进程之服务启动
  20. ShardingJdbc入门

热门文章

  1. [数字媒体] Photoshop基础之图像校正、抠图(证件照)和融合
  2. SQL注入的防御方法
  3. 用来测试的在线视频url地址
  4. PostgreSQL实现批量插入、更新与合并操作的方法_PostgreSQL_脚本之家
  5. 词云分析《天龙八部》人物出现次数
  6. 《智能合约Solidity学习笔记 - 僵尸军团》Part1- 搭建僵尸工厂
  7. 80后创业故事之:兄弟散伙,创业失败
  8. python语言的33个保留字的基本含义_Python入门系列5-保留字和标识符
  9. ubuntu18.04+gtx1660ti+nvidia驱动+cuda10.1+cudnn7.6
  10. 我想跳槽了,该怎么办?,flutter路由切换动画