1、圆形头像:
复制一个builitin-sprite.effect,在片元着色器加入代码:
if(distance(uv0, vec2(0.5, 0.5)) > 0.5){
discard;
}
2、镜面光泽:
复制一个builitin-sprite.effect,在properties中加入颜色属性,以便的编辑器修改镜面颜色:
startColor: { value: [1.0, 1.0, 1.0, 1.0], editor: {type: color} }
endColor: { value: [1.0, 1.0, 1.0, 1.0], editor: {type: color} }
在片元着色器加入全局Uniform和代码:
#include <cc-global>
uniform Constant{
vec4 startColor;
vec4 endColor;
};
vec4 col;
//镜面光泽
float x = uv0.x * 0.6 + uv0.y * 0.2;
if(abs(mod(cc_time.x * 0.5, 1.0) - x) < 0.05){
col = mix(o, startColor * 5.0, 0.1);
}
//镜面光泽垂直颜色变化
#if USE_VERTICAL
col *= mix(startColor, endColor, uv0.y);
#endif
o = col;
3、水波扩散:
复制一个builitin-sprite.effect,在properties中加入属性,以便的编辑器修改:
center: { value: [0.5, 0.5] }
canvas_size: { value: [400, 250] }
wave_radius: { value: 0.05, editor: { slide: true, range: [0, 100], step: 0.1 } }
wave_offset: { value: 2.0, editor: { slide: true, range: [0, 10], step: 0.01 } }
state: { value: 0 }
引入cc-global,可以使用cc_time.x获取游戏运行时间做循环运动:
#include <cc-global>
添加全局Uniform:
uniform Constant{
vec2 center;
vec2 canvas_size;
float wave_radius;
float wave_offset;
int state;
};
在片元着色器加入代码:
if(state == 0){
//如果水波静止,我们看到的其实是像素点围绕着某个中心点的拉伸效果,我们只需让每个像素点叠加上它和中心点的向量差,
//就能够呈现出画面上的所有像素围绕中心点的拉伸感。
vec2 uv = uv0 + normalize(vec2(0.5, 0.5) - uv0) * 0.2;
o = texture(cc_spriteTexture, uv);
}else if(state == 1){
//这个时候如果我们加上时间参数,我们就可以得到一个往外不停井喷的“黑洞”:
vec2 uv = uv0 + normalize(vec2(0.5, 0.5) - uv0) * 0.2 * cc_time.x;
o = texture(cc_spriteTexture, uv);
}else if(state == 2){
//但是水波往外扩散是呼吸灯式的一波波往外涌,而且不是这种无尽式的一直把东西往外掏的感觉,
//所以我们要给`cc_time.x`加上一个周期性的变化,让它能表现出这种周期性的往外扩散的感觉。
vec2 uv = uv0 + normalize(vec2(0.5, 0.5) - uv0) * 0.2 * sin(cc_time.x);
o = texture(cc_spriteTexture, uv);
}else if(state == 3){
//这种呼吸灯式的涌动其实和我们的最终效果有很大区别,因为它永远在循环涌动,但是我们的水波是从中心扩散出去之后,
//中间部分就不再动了的,怎么让中间的像素不再多次涌动呢?如果把一圈水波比作圆,那水波的扩散行为其实就是这个圆的半径在不断的增大,
//圆外面的波纹有效,圆里面的波纹静止。因此我们可以多加一个距离取样,像素离扩散中心的距离大于半径才保留否则丢弃,而这个半径从零开始逐渐增大。
vec2 distance_vec = vec2(0.5, 0.5) - uv0;
float sin_factor = sin(cc_time.x) * 0.2;
float wave_radius = 0.3;
float dis = sqrt(distance_vec.x * distance_vec.x + distance_vec.y * distance_vec.y);
// 其中waveOffset是随时间增长的,通过外部传入
float dis_factor = clamp(wave_radius - abs(dis - wave_offset), 0.0, 1.0);
vec2 uv = uv0 + normalize(distance_vec) * sin_factor * dis_factor;
o = texture(cc_spriteTexture, uv);
}else if(state == 4){
//接下来的就是参数的调试,主要是三角函数的采样那里,我们希望水波能够产生多个波动,所以我们需要乘上一定的倍数,
//让函数的作用范围足够大,才能有足够多的波峰谷底。另外就是sin函数的输出值域在`(-1, 1)`之间,
//所以我们的输出也需要缩小一定的倍数,才能让函数的峰值变化处于一个合理的范围。
vec2 distance_vec = center - uv0;
distance_vec *= vec2(canvas_size.x / canvas_size.y, 1.0);
float dis = sqrt(distance_vec.x * distance_vec.x + distance_vec.y * distance_vec.y);
float sin_factor = sin( dis * 100.0 + cc_time.x) * 0.05;
float discard_factor = clamp(wave_radius - abs(wave_offset - dis), 0.0, 1.0);
//计算总的uv偏移值
vec2 offset = normalize(distance_vec) * sin_factor * discard_factor;
vec2 uv = uv0 + offset;
o = texture(cc_spriteTexture, uv);
}else if(state == 5){
vec2 distance_vec = normalize(vec2(0.5, 0.5) - uv0);
float dis = sqrt(distance_vec.x * distance_vec.x + distance_vec.y * distance_vec.y);
vec2 uv = distance_vec * tan(distance_vec.y / distance_vec.x * .1) * tan(distance_vec.x * .1 / distance_vec.y ) + uv0 + cc_time.x;
o = texture(cc_spriteTexture, uv);
}