背景
-
第一篇描述了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