Cocos Creator Shader Effect 系列 - 5 - 马赛克/像素化特效

本章为大家带来马赛克/像素化特效。

马赛克和像素化特效有点类似,只不过程度不同,视乎格子的数量多少,可以认为是马赛克,也可以认为是像素化

2d-sprite-mosaic.gif

一、马赛克特效原理

马赛克的原理很简单,一句话形容就是 m x n 方块内取同一颜色 ,具体为两个步骤:

  1. 将纹理分成 m x n 个方块
  2. 方块内取同一个颜色

至此,本章完,你已经可以根据这个原理去实现效果了。

二、马赛克代码实现

将纹理分成 m x n 个方块 ,m 和 n 应该属于外部控制,因此我们将这两个属性设置为uniform变量,并定义如下:

uniform Mosaic {
  // X轴方块数量
  float xBlockCount;
  // Y轴方块数量
  float yBlockCount;
}

那么我们又如何实现方块内取同一个颜色呢?其中一种解决方案

  1. 计算顶点所在方块
  2. 取该方块内某一点,代表该方块的颜色

举个例子:

图中A点,B点,我们很明显知道它是落在方块 (1,0) 上,按照上面的操作,实际上,A,B两点采用的是方块(1,0) 的颜色,这里也可以变相理解为 A,B两点的坐标映射(或者叫投影)到格子(1,0) 的坐标

explain

抽象一下,实际的问题就变为:

我们怎么计算某个点的映射格子呢?这里,我们尝试分步计算

2.1 计算点在X轴上坐落的格子

首先,X轴上,每个格子的宽度可以这样子求解

float blockWidth = 1.0 / xBlockCount;

为了避免 xBlockCount 为 0 的问题,导致出现除以 0 的问题,我们可以这样子优化一下:

// 计算x轴格子宽度
float xCount;
if (xBlockCount <= 0.0) {
  xCount = 1.0;
} else {
  xCount = xBlockCount;
}
float blockWidth = 1.0 / xCount;

然后,用点的X坐标除以格子的宽度,然后向下取整,就可以得出点在X轴上哪个格子了

float blockXIndex = floor(v_uv0.x / blockWidth); 

2.2 计算点在Y轴上坐落的格子

同理,我们也可以求出点在Y轴上的哪个格子:

// 同理,求出当前 v_uv0 在y轴上的哪个格子
float yCount; 
if (yBlockCount <= 0.0) {
  yCount = 1.0;
} else {
  yCount = yBlockCount;
}
float blockHeight = 1.0 / yCount;
float blockYIndex = floor(v_uv0.y / blockHeight);

2.3 计算格子颜色

现在我们知道点是坐落格子是 (blockXIndex, blockYIndex) ,那么这个格子取什么颜色呢?

一般而言,我们取格子中心点所在颜色作为格子的颜色,当然你也可以有不同的实现。

计算格子中心点其实也很好算

// X:格子宽度 * 格子索引 + 半个格子的宽度
// Y:格子高度 * 格子索引 + 半个格子的高度
vec2 pos = vec2(blockWidth * blockXIndex + blockWidth * 0.5, blockHeight * blockYIndex + blockHeight * 0.5);

// 即
vec2 pos = vec2(blockWidth * (blockXIndex + 0.5), blockHeight * (blockYIndex + 0.5));

OK,现在我们可以得出了完整的映射代码

code

通过上面这份代码,我们就可以将顶点映射到不同格子,并且实现同一个格子显示同一个颜色(颜色为格子中心点的颜色)了。

2.4 应用映射

片段着色器 中应用一下映射刚刚的映射函数,更新每个 uv0 的实际映射坐标:

CCProgram fs

加上一些我们在 Cocos Creator Shader Effect 系列 - 3 - Effect 文件调试 中说到的调试手段,你就能得到马赛克的效果了

2d-sprite-mosaic.gif

三、总结

从上面的动图,你可以看到,视乎格子数量多少,一定程度上可以叫马赛克,在另外一个程度上,也可以叫像素化,重点在于 格子数量 这个变量,实际使用的时候,我们可以根据自己的需求去进行控制。

另外一个点就是,本张我们介绍了点映射或者叫 点投影 ,这是一个很好玩的操作,不同的投影方式能产生不同的效果,可以想点什么效果,去试试玩~

OK,本章完,完整代码在我的 Github 仓库Gitee 仓库 中可以找到。

下一篇:

上一篇:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容

  • 此刻,秋风乍起,片片落叶皆写满诗意,然我却终究提不起兴趣来写一首关于秋天的诗。 许是秋天并未真正携着清风到来的缘故...
    阜南小乔阅读 2,583评论 39 44
  • 2017年12月初,承蒙公司特意安排,我们同事一行7人去了云南旅游。在云南,我们不但领略了玉龙雪山的沧桑与活力,而...
    轮胎配方工匠阅读 251评论 3 1
  • “格”是人格,“局”是胸怀。做人做事不仅要注重细节,更要具有胸怀。两者相得益彰...
    冰夫阅读 133评论 0 0
  • 面向对象:点餐的菜单是直接面对点菜,这是面向对象。 面向对象过程:后厨厨师做饭,如何做,先放什么后放什么。 *对象...
    if_mflz阅读 164评论 0 0