Flutter & GLSL - 肆 | 从条纹到马赛克

Flutter & GLSL 系列文章:

案例代码开源地址 【skeleton】


1. 实现条纹

之前我们实现过黑色到红色的渐变效果,让像素颜色的 r 值根据坐标从 0~1 均匀变化即可。现在想要实现如下的 渐变条纹 ,该怎么办呢?条纹可以指定个数,如下是 10 个条纹从黑到红的渐变效果:

对于 shader 要解决抓住一点:通过坐标控制像素的颜色信息 。下面着色器代码中通过 count 表示条纹的数量;floor 函数是一个内置函数,用于对数字取整。

比如 floor(0.9) = 0floor(1.9) = 1 ; 利用这个性质通过 floor(coo.x * count), 可以将 [0->1] 连续的 coo.x 变成:在某个取值范围间是恒定值。比如

count =10 时,coo.x 在 [0,0.1) 时, floor(coo.x * 10) 恒为 0 ;

count =10 时,coo.x 在 [0.1,1) 时, floor(coo.x * 10) 恒为 1 ;

count = 8 时,coo.x 在 [3/8,4/8) 时, floor(coo.x * 8) 恒为 3 ;

于是 floor(coo.x * count)/ count 在 coo.x 从 0->1 取值时,会依次形成 count 个从 0->1 依次增加的恒值。将不同的恒值作为 r 通道的数据,就可以得到在 某段横坐标区域 内颜色相同的效果:

c 复制代码
#version 460 core
#include <flutter/runtime_effect.glsl>

precision mediump float;

out vec4 fragColor;
uniform vec2 uSize;

void main() {
    vec2 coo = FlutterFragCoord().xy / uSize;
    float count = 10.0;
    float x = floor(coo.x * count)/ count;
    fragColor = vec4(x,0,0,1);
}

2. 对贴图进行类似操作

图片本质上就是一个个像素颜色信息,着色器中通过 texture 函数根据坐标值拾取颜色。如果坐标值不按常规操作,让横坐标在某些区域内相同,会有什么效果呢?

count=10 count=20 count=50

下面代码中,对横坐标 x 进行运算,使得在某段横坐标区域内,取用同一横坐标值,纵坐标 y 维持原状。这样就可以得到 count 个图片条纹,视觉上每段区域的效果是:最左侧的边线向右平移擦出的痕迹。

当 count 越大时,条纹越多,看起来图片就越清晰。这里已经有点马赛克的味道了。

c 复制代码
#version 460 core
#include <flutter/runtime_effect.glsl>

precision mediump float;

out vec4 fragColor;
uniform vec2 uSize;
uniform sampler2D uTexture;

void main() {
    vec2 coo = FlutterFragCoord().xy / uSize;
    float count = 10.0;
    float x = floor(coo.x * count)/ count;
    fragColor = texture(uTexture, vec2(x,coo.y));
}

3. 矩形马赛克

上面只对横轴 x 进行操作,得到了图片 条纹 ;那么同时对 x,y 坐标进行操作,就可以得到图片 点阵。也就是我们常见的马赛克:

count=10 count=20 count=50

代码的实现也非常简单,对于 y 进行类似的操作即可:

c 复制代码
#version 460 core
#include <flutter/runtime_effect.glsl>

precision mediump float;

out vec4 fragColor;
uniform vec2 uSize;
uniform sampler2D uTexture;

void main() {
    vec2 coo = FlutterFragCoord().xy / uSize;
    float rowCount = 50.0;
    float x = floor(coo.x * rowCount)/ rowCount;
    float y = floor(coo.y * rowCount)/ rowCount;
    fragColor = texture(uTexture, vec2(x,y));
}

从条纹到马赛克,我们通过一个小小的、普通的 floor 函数,就实现图片的特效。是不是非常有趣,后面还会带来其他马赛克效果的解析。最后还是想强调一点:着色器的奥义是 通过坐标控制像素的颜色信息,一定要牢牢抓住这点。那本文就到这里,谢谢观看 ~ 我们下次再见

相关推荐
北漂Zachary1 小时前
四大编程语言终极对比
android·java·php·laravel
吴声子夜歌3 小时前
Vue.js——自定义指令
前端·vue.js·flutter
学习使我健康6 小时前
Android App 启动原理
android·android studio
TechMix6 小时前
【性能工具】atrace、systrace、perfetto抓取的trace文件有何不同?
android·性能优化
张小潇7 小时前
AOSP15 WMS/AMS系统开发 - 窗口层级源码分析
android·前端
liulian09169 小时前
Flutter 三方库 flutter_local_auth 的鸿蒙化适配指南
flutter·华为·学习方法·harmonyos
努力努力再努力wz9 小时前
【MySQL入门系列】掌握表数据的 CRUD:DML 核心语法与执行逻辑解析
android·开发语言·数据结构·数据库·c++·b树·mysql
qwfy10 小时前
瑞幸 UI 上 pub.dev 了 —— 22 个 Flutter 组件,与微信小程序版双端对齐
flutter·开源
zh_xuan11 小时前
Android gradle任务
android·gradle构建
Grackers12 小时前
Android Perfetto 系列 10:Binder 调度与锁竞争
android·binder