在上个章节中,我们以抖音故障特效为例,为大家详细讲解了如何让特效动起来,以及如何实现一个较复杂特效。那么本章我们继续为大家讲解webgl滤镜技术中的多滤镜叠加技术,这一技术常应用于各大美颜软件,滤镜相机中,我们可以通过多层滤镜混合来实现更酷炫的效果,如下图中就混合了 抖音故障特效和电影特效。
帧缓冲
在开始正式实现该效果之前,我们先要向大家普及一个概念,帧缓冲,它便是实现多滤镜叠加的核心技术点。
帧缓冲简介
帧缓冲(Framebuffer Object),简称 FBO,它是用于写入颜色值的颜色缓冲、用于写入深度信息的深度缓冲和允许我们根据一些条件丢弃特定片段的模板缓冲的结合,之前的操作我们都是在默认帧缓冲的渲染缓冲中进行,也就是我们的窗口。除此之外,OpenGL允许我们定义我们自己的帧缓冲,也就是说我们能够定义我们自己的颜色缓冲,甚至是深度缓冲和模板缓冲(本次滤镜场景暂不涉及后两种缓冲类型),用来作为绘制的载体,当在自己的 FBO 上绘制好了之后,可以再把绘制内容显示到屏幕上,实现更多酷炫的效果。
帧缓冲的基本应用
这里需要注意,上述代码并不是帧缓冲的所有api实现,这里只是针对2d图像渲染场景,帧缓冲的应用场景十分丰富,有兴趣的同学可以单独查阅资料了解。
多滤镜叠加
介绍完了帧缓冲,那么我们就开始正式讲解它的多滤镜叠加中的具体应用,对于 webgl
来说,多滤镜叠加其实就是利用帧缓冲离屏渲染的能力,通过循环多个 shader
程序对纹理进行反复渲染,最终达到所有shader渲染完成后再上屏的操作。
接下来的讲解会大量与系列文章第一篇重合,主要差别会在流程中标记*。这里建议大家,如果你对 webgl
还没有一定的认识,建议可以先阅读系列文章的第一篇和第二篇,更有利于本章的理解。
半小时轻松玩转WebGL滤镜技术系列(一) 如何绘制图像以及基本滤镜实现介绍
半小时轻松玩转WebGL滤镜技术系列(二) 以抖音故障特效为例解析复杂特效
前期准备
首先我们将要叠加的滤镜数据准备好
start.js
加载纹理图片
start.js
创建canvas,获取WebGL绘图上下文
index.html
start.js
* 初始化着色器
start.js
initShader.js
创建 shader
程序的逻辑与之前单一 shader
程序相同,这里我们重点关注最后几行,由于在第一章中我们是单一的 shader
程序,所以我们会直接使用 shader
程序并保存在 gl
的属性中
而在多shader中,我们的使用操作要滞后, program
也要保存在相应的 shader
对象中
* 设置顶点位置
start.js
initVertexBuffers.js
在设置顶点位置的流程中,我们可以看到,原有的一个函数被拆分为了两个,这是因为各个 shader
程序需要独立的传入顶点坐标,这里需要注意,我们只传入了顶点坐标,并没有传入纹理坐标,这部分是因为我们将纹理坐标的计算融合进了顶点着色器中,文末会给出具体的着色器代码。
* 配置图像纹理
start.js
initTexture.js
需要注意的是这里我们删除了跟具体 shader
程序相关的部分,具体原因在下一步说明
* 绘制图像
start.js
最终实现效果如下
这里我们可以看出已经跟单 shader
有较大的区别,首先我们循环当前滤镜数组,对每一个 shader
对象进行一次绘制,在 drawScene
函数中,当我们进行第一次渲染的时候,我们将 source
设置为原始的图片纹理,将 target
设置为新创建的帧缓冲对象,这里需要注意的是,我们在配置图像纹理步骤中省略掉的传递纹理的步骤挪到了这里,在第一次渲染的时候激活了0号图像纹理并且将0号纹理传递给着色器的取样器变量(其实在单一图像纹理时我们可以不主动声明,默认会取 0号图像纹理并激活传入 ),在后续渲染时, source 取上一次渲染好的帧缓冲纹理,而 target 进则是设置为存储好的 fbo
对象,这样进行反复的 shader
程序处理,直到最后一次,我们将 target
设置为 null
,代表我们要将反复处理的帧缓冲当做图像纹理绘制到屏幕上,由此便实现了多滤镜叠加的效果。
总结
在本章,我们通过帧缓冲的特性来实现了多滤镜叠加的效果,同样,通过多滤镜叠加这一特效,也使我们对帧缓冲这一特性有了更高的认识。当然,多滤镜叠加只是帧缓冲技术点的一个落地场景,更多的运用,更多的可能,我们或在探索,或在积累。技术始终还是要落地于实际应用场景,而强大的技术则能够为我们的应用带来无限可能。在后续,我们依然会为大家带来更加丰富实用的webgl相关知识,更多精彩,敬请期待。
最后附上我们本次使用的 shader
着色器代码
顶点着色器
注意:纹理坐标我们直接通过顶点坐标进行计算
片段着色器
-
glitcher.glsl
故障特效在第二章中已经有较为详细的讲解,这里需要注意在最后计算随机值得时候,为了避免时间为0的情况,我们加上offset便宜量得到一个较小值参与随机计算。
-
film.glsl
注: 该部分参考部分开源shader
电影效果主要包含的就是噪点和扫描线的生成,通过上一节对于故障特效的分析,同学们可以试着分析一下电影效果其中的奥妙。
注意:两个shader中均有注释的部分,如果你已经看过系列前两章,应该会比较清楚,注释掉的就是动态传参的部分,我们在这里为了突出重点直接写死了其值。当你实现了本章的效果后,你可能会想,借助第二章的原理我能不能让图片动起来呢,那么这些参数就派上用场了,这里也给大家留下一些深入的空间,如何动态给多滤镜程序传参呢?这里给大家一个小tip,注意传参时区分program.
始发于微信公众号: 腾讯DeepOcean
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)
- HQChart 1.9500 版本发布, 分时图支持叠加多个指标
- Istio与Kubernetes叠加后的快感从何而来?
- c# – 如何将两个图标合并在一起? (在另一个图标上叠加一个图标)
- CSS教程:图片使用混合模式和颜色叠加filter滤镜,改变PNG图标颜色
- 网页模板 | 12倒计时15背景12多概念18预定颜色9叠加模式HTML5和CsS3
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
在线进制转换器
各进制数互转换器
UNIX 时间戳转换
UNIX 时间戳转换