火影推荐程序连载6-径向模糊简介
径向模糊,是一种从中心向外呈幅射状,逐渐模糊的效果。 因此径向模糊经常会产生一些中心的发散效果,在PS中同样也有径向模糊的滤镜效果。 径向模糊通常也称为变焦模糊。径向模糊(Radial Blur)可以给画面带来很好的速度感,是各类游戏中后处理的常客,也常用于Sun Shaft等后处理特效中作为光线投射(体积光)的模拟。
在游戏中,常常使用径向模糊来模拟一些运动的动感效果。如鬼泣4中的场景切换特效,和一些技能打击特效;赛车游戏也尝用来模拟动感模糊,如狂野飙车,极品飞车等。 径向模糊还是实现体积光照的一种技术手段之一,如下图:
径向模糊的原理
图形学中模糊的大致原理都是一样的:就是从原像素周围去寻找附近像素的颜色,来共同影响当前的像素颜色。如高斯模糊就是将原像素四周像素的颜色加权求和作为原像素的颜色以达到模糊的目的。
不同的模糊就是取周边像素和加权求和的算法不太一样。径向模糊的特点是从某个中心点向外散射扩散,因此其需要采样的像素来自于当前的像素点和中心点的连线上,通过参数可以控制采样的数量和采样步进的距离。像素的颜色是由该像素的点与中心点之间连线上进行采样,然后求将这些采样点颜色的加权平均。根据径向模糊的特性,离目标点越近采样点越密集,反之亦然。
因此,实现径向模糊的大致流程如下:
- 确定径向模糊的中心点,一般为画布的中心点,或这个某个对象的中心点在屏幕投影所在的位置。(注意中心点是2维坐标)
- 计算当前像素和中心点的距离和向量线段。
- 在线段上面进行采样,加权。
- 将模糊的结果和原图进行一个叠加合成(可能需要)
webgl实现径向模糊
径向模糊是一个后处理过程,径向模糊可以对静态的图片施加效果,也可以对动态渲染的图像施加效果。本示例中将对动态的图像施加效果。先上一张图看看效果:
首先绘制的几个圆环对象,然后对绘制的图像施加径向模糊。
渲染到纹理
要施加径向模糊,首先要把圆环绘制到texture对象上面,我们知道,通过framebuffer的技术,可以实现把绘制效果输出到贴图对象上。
有关framebuffer的技术,不属于本文重点介绍的内容,如果读者不熟悉,可以自行查找相关资料。也可以参考:渲染到纹理。
输入贴图对象
要把贴图对象输出到屏幕上面,我们需要构造一个矩形对象,该对象正好是webgl坐标系中的四个顶点,代码如下:
function quad() {var pos = [-1,1,0, -1,-1,0, 1,-1,0, 1,1,0],st = [0,1,0,0,1,0, 1,1],idx = [0,1,2,0,2,3];return {p:pos,t:st,i:idx,}
}
上述对象可以正好把一个贴图对象完整的输出到屏幕上(webgl坐标系)
实现径向模糊
径向模糊的主要在着色器语言中进行实现,而且主要是在片元着色器中,下面是片元着色器的代码:
var ofs = `precision mediump float;
uniform sampler2D texture;
uniform float strength;
varying vec2 vTexCoord;const float tFrag = 1.0 / 512.0;
const float nFrag = 1.0 / 30.0;
const vec2 centerOffset =www.tyyleapp.com vec2(256.0, 256.0);float rnd(vec3 scale, www.lafei6d.cn float seed) {return fract(sin(dot(gl_FragCoord.stp + seed, scale)) * 43758.5453 + seed);
}vec4 fragRadialBlur(){vec2 fc =www.xingchenylzc.cn vec2(gl_FragCoord.s, 512.0 - gl_FragCoord.t);vec2 fcc =www.yifayuled.cn fc -www.fudayulpt.cn centerOffset;vec3 destColor www.pinguo2yl.com= vec3(0.0);float random =www.jinmazx.cn rnd(vec3(12.9898, 78.233, 151.7182), 0.0);float totalWeight = 0.0;for (float www.qilzixyouyi.com = 0.0; i <= 30.0; i++) {float percent =www.lecaixuangj.cn (i + random) * nFrag;float weight = percent - percent * percent;vec2 t www.hongtuuzhuc.cn= fc - fcc * percent * strength * nFrag;destColor += texture2D(texture, t * tFrag).rgb * weight;totalWeight += weight;}return vec4(destColor / totalWeight, 1.0);
}void main(void) {gl_FragColor = fragRadialBlur();}`;
随机函数
首先声明了一个rnd函数,此函数是一个简单的随机数生成器,当给定向量和种子值时,将返回0到1范围内的随机数。
使用随机数,是为了让模糊的效果呈现一定的随机状态,而不是按照某种一致性的原则进行模糊。
rnd 在每次片元着色器中都会调用,因此要尽量使用轻量化的实现,不然可能会造成性能负载。
定义相关变量
const float tFrag = 1.0 / 512.0;
const float nFrag = 1.0 / 30.0;
const vec2 centerOffset = vec2(256.0, 256.0);
然后定义相关变量。在此示例中,缩放的中心点设置为画布的中心。
画布的大小为512像素,因此上面的代码相应地声明了一些常量。
vec2变量centerOffset用于定义中心位置。
floag变量tFrag用于规范化,把二维顶点坐标转换成归一化为uv坐标,以正确引用着色器中的纹理像素。
另一个float类型常量nFrag用于着色器中for的语句进行迭代处理进行归一化。
径向模糊逻辑
vec4 fragRadialBlur(){vec2 fc = vec2(gl_FragCoord.s, 512.0 - gl_FragCoord.t);vec2 fcc = fc - centerOffset;vec3 destColor = vec3(0.0);float random = rnd(vec3(12.9898, 78.233, 151.7182), 0.0);float totalWeight = 0.0;for (float i = 0.0; i <= 30.0; i++) {float percent = (i + random) * nFrag;float weight = percent - percent * percent;vec2 t = fc - fcc * percent * strength * nFrag;destColor += texture2D(texture, t * tFrag).rgb * weight;totalWeight += weight;}return vec4(destColor / totalWeight, 1.0);
}
首先,通过gl_FragCoord计算出变量fc,表示当前像素在canvas画布的坐标。 注意gl_FragCoord坐标的原点是在左下角,而canvas画布的坐标原点在左上角,应此做了一个翻转计算:
512.0 - gl_FragCoord.t
计算变量fcc,表示当前坐标到中心点的向量。
定义变量destColor用于保存最终要输出的像素颜色。 然后计算一个随机值random。totalWeight表示每次迭代时候采样像素所占的比重之和。
然后开始迭代处理。
在片段着色器中通过for语句进行迭代处理,使用i加上随机数之和来计算目标像素的percent(比重),然后通过percent - percent * percent 是为了把线性的比重数据变成非线性的比重weight。
然后通过percent和strength计算出一采样的坐标点t,其中strength表示径向模糊的强度,此值越大,偏离越大,模糊效果越强。并通过texture2D函数获取对应坐标点的颜色值,然后乘以weight并加入到destColor,并最终计算totalWeight。
最后,完成迭代过程后进行归一化destColor: destColor / totalWeight。
说明
此处我们使用了30次迭代,看起来性能并没有太大影响。实际过程中,可以选择不同的迭代次数,来达到效果和性能的平衡。
最终效果如下,
本文也发表在我的webgl专栏,完整代码可以在专栏中获取:
https://xiaozhuanlan.com/topic/6480975213
下一篇文章讲述利用径向模糊实现体积光的效果,先上一张图看看效果:
火影推荐程序连载6-径向模糊简介相关推荐
- 火影推荐程序连载32-我是如何使用freemarker生成Word文件的?
背景 一天,产品经理递给我了一份word报告,我定睛一看 这个文档有大大小小的标题层级,还有排版好的段落.各种一目了然的饼图.走势图,当然还少不了颜色循环交替的报表.精致程度不亚于小明同学的学习报告. ...
- 火影推荐程序连载16-聊聊前端监控——错误监控篇
当有人问起:你们的公司的这款应用用户体验怎么样呀?访问量怎么样?此时,你该怎么回答呢?你会回答:UV.PV 巴拉巴拉,秒开率.FP.TTI 巴拉巴拉. 那么,这些数据是哪里来的呢?显而易见,这些数据都 ...
- 火影推荐程序连载56-linux硬盘分区及挂载
这是一个系列的文章,打算把Redis的基础数据结构.高级数据结构.持久化的方式以及高可用的方式都讲一遍,公众号会比其他的平台提前更新,感兴趣的可以提前关注,「SH的全栈笔记」,下面开始正文. 如果你是 ...
- 火影推荐程序连载14-Vue开源项目使用探索
前言 本文记录一次使用Vue开源项目的过程. 寻找Vue开源项目 要使用Vue开源项目就必须先找到一个,我们去Github上搜索[后台],然后使用Vue分类进行检索,找到排名第一的开源框架 然后新建一 ...
- 火影推荐程序连载52-什么是Serilog?
上文说到Nlog日志框架,感觉它功能已经很强大,今天给大家介绍一个很不错的日志框架Serilog,根据我的了解,感觉它最大的优势是,结构化日志,它输出的日志是Json的格式,如果你使用的是Mongod ...
- 火影推荐程序连载23-Robot Framework自动化测试框架核心指南-如何做好自动化测试平台框架的设计
自动化测试如果需要能高效快速的支撑软件项目的测试,项目的快速迭代以及上线,除了以上我们介绍的需要许多的Lib来支持以及需要高效的去编写自动化测试案例外,还需要一个好的自动化测试框架平台来支撑我们的自动 ...
- 给Lisp程序员的Python简介
给Lisp程序员的Python简介 作者:Peter Norvig,译者:jineslong<zzljlu@gmail.com> 这是一篇为Lisp程序员写的Python简介(一些Pyth ...
- 经典推荐--程序员之打油诗
经典推荐--程序员之打油诗 写字楼里写字间,写字间里程序员:程序人员写程序,又拿程序换酒钱. 酒醒只在网上坐,酒醉还来网下眠:酒醉酒醒日复日,网上网下年复年. -- 宁愿老死程序间,只要老板多发钱:小 ...
- 六款值得推荐的Android开源框架简介
六款值得推荐的Android开源框架简介 技术不再多,知道一些常用的.不错的就够了.下面就是最近整理的"性价比"比较高的Android开源框架,应该是相对实用的. 1.volley ...
最新文章
- CodeCraft-21 and Codeforces Round #711 (Div. 2)
- 判断一个无符号整数是不是2的幂
- rr计算机专业英语,《计算机专业英语》电子教本8.pdf
- 如何进入HPunix的单用户模式
- 置为底层_头一次见浴室装修这样设计,浴缸两头砌上置物台,实用又方便
- c语言extern_C语言中#if,#if defined ,#ifdef,extern的用法描述
- 微软将 Teams 移动应用纳入漏洞奖励计划,最高奖金3万美元
- iOS - 正则表达式判断邮箱、身份证..是否正确
- javascript案例---简单的视觉效应
- 教你如何下载并破解IAR
- php性格属于哪类,狗狗性格分为6大类,你家是属哪一类?快来是看聪明型还是粘人型...
- java 多定时任务_多机部署之定时任务完整方案
- Ubuntu中shell命令-(4)-echo/tar/which/whereis/ps/kill/top/df/du
- 分布式系统上下层概念抽象-(2)
- 一个关于LSTM生成歌词的练习
- Flux脚本语言基础使用-函数定义(InFluxDB 查询语言)
- 这5个“减压”小妙招,在你负重前行的路上会用到!
- stlink制作(OSHW版)
- Chrome 十周年亮出大招:彻底干掉URL!
- codeforces 1278 B. A and B