前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >马赛克效果(shader)

马赛克效果(shader)

作者头像
异名
发布2020-06-08 18:56:42
2K0
发布2020-06-08 18:56:42
举报
文章被收录于专栏:异名

马赛克是一种常用的图像处理手段,因为这种模糊效果看上去有一个个的小格子组,便形象的称这种画面为马赛克。当画面上的马赛克格子小到一定程度的时候,画面呈现出来的风格也叫像素风

demo

实现思路

核心思路就是把图片划分成M * N个小格子,格子内取同一个颜色。我们前面经常用到texture(texture, v_uv0)这个函数,它的作用就是把纹理贴图按uv进行取样,输出一个vec4类型的颜色值,在实现马赛克效果的时候我们改为按M * N个点来取样,也就是要找出每个格子的中心点,然后传入texture函数,这样一来问题就变成了,如何计算每个格子的中心点

从水平方向说起,每个格子的x轴中心坐标等于当前格子的x轴位置加上格子宽度的一半。格子数量x_count通过外部传入,每个格子的宽为block_w = 1.0 / x_count,每个格子的x轴位置等于当前格子的序号乘上格子的宽度,格子的序号为block_x_idx = floor(v_uv0.x / block_w),当前格子的位置为block_x_idx * block_w,当前格子的中心点位置为block_w * (block_x_idx + 0.5)。同理可以得到格子中心点的垂直方向的位置:

代码语言:javascript
复制
vec2 getUvMapPos() {
  float block_w = 1.0 / x_count;
  float block_x_idx = floor(v_uv0.x / block_w);

  float block_h = 1.0 / y_count;
  float block_y_idx = floor(v_uv0.y / block_h);

  return vec2(block_w * (block_x_idx + 0.5), block_h * (block_y_idx + 0.5));
}

有了映射的坐标,我们就可以直接进行颜色取样和赋值,为了便于控制,我们还可以加上一个宏开关:

代码语言:javascript
复制
void main () {
  vec4 o = vec4(1, 1, 1, 1);
  vec2 realPos = v_uv0;

  #if USE_MASAIC
    realPos = getUvMapPos();
  #endif

  o *= texture(texture, realPos);
  o *= v_color;

  gl_FragColor = o;
}

后面可以通过更改传进来的垂直和水平方向的格子数量来控制马赛克的大小,效果如下:

demo

效果预览

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 异名 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现思路
    • 效果预览
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档