美文网首页
Cocos Creator Shader Effect 系列 -

Cocos Creator Shader Effect 系列 -

作者: 天煞魔猎手 | 来源:发表于2020-01-06 09:58 被阅读0次

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

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

    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 仓库 中可以找到。

    下一篇:

    上一篇:

    相关文章

      网友评论

          本文标题:Cocos Creator Shader Effect 系列 -

          本文链接:https://www.haomeiwen.com/subject/gtqgoctx.html