模仿江南百景图shader效果之二 实现篇

背景

  • 第一篇描述了shader如何自定义顶点格式,地址是

  • 这篇是实现篇,实现效果如下,一开始图片以灰度显示一段时间,然后随着时间的流逝,在垂直方向慢慢的向中间填充彩色。具体如下:

彩色全景

地图

  • 由于主要展示的shader的效果,这里只是简单描述一下一种实现思路。

  • 地图分几层,可能分为地表层、建筑层、和天空层,每一层有一个相同的图集,然后每层,可以用tilemap之类的工具进行布局。

  • 摄像头里面的tile可见,之外的不可见,这只需要用到矩形碰撞的的算法就可以了,矩形碰撞的算法网上可查。

  • 地块由不可见到可见,会有一个管理器管理每个地块的时间参数,这个参数会传到shader里面。而地块由可见变为不可见,地块的时间参数会重置。

shader效果的实现

  • 涉及计算的变量。

float cx = customData.x; //时间参数

float top = customData.y; //uv上边界;

float down = customData.z; //uv下边界;

float center = (top - down) /2.0; //uv上下边界的中心

float y = uv0.y; //片段着色器当前的uv的y坐标

  • 时间参数从0逐渐插值到1,从0到0.3的区间先显示灰色。

o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);

float gray = (0.4126 * o.r + 0.5152 * o.g + 0.0722 * o.b); //灰色

if(cx >= 0.0 && cx <= 0.3){ //cx是时间参数

    o = vec4(gray,gray,gray,1.0);

}

  • 时间参数从0逐渐插值到1,从0.3到1的区间,逐渐从上下两边填充彩色。下面以上半部分为例说明。由于变化是线性的,所以变化的方程是二元一次方程,即y=ax+b,y是需要填充到的uv边界,x是时间参数,再将已知的两个点带入,即可求得a和b,得到最终方程式。如下:

  • 以上半部分为例,代码是:

/** 时间参数从0.3到1.0*/

if(cx >0.3){

    /**

     * 第一个判断条件,uv0.y < center 为上半部分

     * 第二个判断条件,当uv0.y大于某一个数值(随时间参数变化,由上面方程求得),还是显示灰色,否则显示彩色。

     */

    if (uv0.y < center && uv0.y > (center - down)*cx /0.7 + (down - 0.3 *(center - down)/0.7)){

        o = vec4(gray, gray, gray, 1.0);//灰色

    }else{

        o = vec4(o.r,o.g,o.b,1.0);//彩色

    }

}

总结

  • 由于使用了自定义顶点数据格式,最终的效果是同一层的tile,只有一个dc。

  • 第一篇详细解析了使用自定义顶点数据格式的一种方式,第二篇主要是使用一个二元一次方程式,得到最终的效果。

笔者qq/wx:408293635

ps,笔者正在寻找base广州的机会,如果合适的话,请加我wx

完整的项目代码,在商城:
https://store.cocos.com/app/detail/5440

1赞

支持下 写的不错