Cocos Shader 高性能转场特效合集!免费开源!二次元卡牌必备!

新闻资讯   2023-07-21 17:04   121   0  

引言:Cocos Creator 3.8.0 正式版本正在紧锣密鼓地准备中。在等待新版本的同时,社区的高产大户孙二喵同学给大家带来了 7 种炫酷的 Cocos Shader 转场特效方案,并附带了源码。

本文是孙二喵用 AIGC 制作的卡牌游戏项目中的产物,有兴趣的同学可以查看之前的文章:AIGC 制作 3D 贪吃蛇游戏 和 AIGC 制作卡牌游戏

前言

我利用 AIGC 工具配合 Cocos Creator 制作的卡牌游戏项目已接近尾声。

但最近遇到一个很头疼的问题,就是如何又流畅、又生动地实现转场效果。

在经过一番摸索后,最终我使用了 Cocos Shader 来实现,借助 GPU 的运算能力,这些转场特效可以高效地运行在各个平台。

在这个过程中,我实验了多个效果,一共写了 7 个转场特效,现在分享给大家,希望对大家有所帮助。

预览地址:http://learncocos.com/shader1/

接下来就让我们看看具体的实现以及对应的效果。

注意:参与转场效果的图片不能参与合图,合图会因为 UV 被转换导致效果不对。在 Assets 中选择对应图片,在属性面板中取消勾选 Packable 属性即可。

01 线性转场

转场的 Shader 需要两张图片,主图片使用默认的精灵,需要转场的图片,我们可以新建一个 subTexure 属性。

线性转场效果相对比较简单,关键的 Shader 代码如下:

#include <builtin/uniforms/cc-global>

const float tranSize = 0.1; 
vec4 LinearTransition(vec4 color,vec4 mixcolor, vec2 uv, float progression,bool isUVX) {
  float dir = isUVX?uv.x:uv.y;
  float f = dir*(1.0-tranSize) + tranSize - (progression * (1.0 + tranSize));
  float m = smoothstep(0., -tranSize,f);
  color = mix(color,mixcolor,m);
  return color;
}

这里使用了 smoothstep 函数,我们先看下 smoothstep 的源码:

float smoothstep(float t1, float t2, float x) {
  // Scale, bias and saturate x to 0..1 range
  x = clamp((x - t1) / (t2 - t1), 0.0, 1.0); 
  // Evaluate polynomial
  return x * x * (3 - 2 * x);
}

从源码中可以看出,它根据 x 在 t1 和 t2 之间的距离,返回 [0,1] 的平滑过渡值。

这里使用了 f = dir *(1-s)+s-p*(1+s) 使选定的 uv 轴向,返回在进度参数下的混合系数

最终实现的效果如下:

02 风吹线性过度

在线性转场的基础上加入随机的风吹效果,Cocos Shader 代码如下:

#include <builtin/uniforms/cc-global>

// Variables
const float tranSize = 0.25; 

float rand (vec2 co) {
  return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

vec4 WindTransition(vec4 color,vec4 mixcolor, vec2 uv, float progression) {
  float r = rand(vec2(0, uv.y));
  float m = smoothstep(0.0, -tranSize, uv.x*(1.0-tranSize) + tranSize*r - (progression * (1.0 + tranSize)));
  color = mix(color,mixcolor,m);
  return color;
}

最终实现的效果如下:

03 圆形过度

#include <builtin/uniforms/cc-global>

float rule(vec2 coord)
{
    vec2 uv2 = coord - vec2(0.5, 0.5);
    float angle = atan(uv2.x, uv2.y);
    return angle / 2.0 / 3.1416 + 0.5;
}

vec4 CircleTransition(vec4 color,vec4 mixcolor, vec2 uv, float progression) {
  float rule = rule(uv);
  float vague = 0.2;
  float phase = progression * (1.0 + vague);
  float p0 = smoothstep(rule, rule + vague, phase);
  color = color * (1.0 - p0) + mixcolor * p0;
  return color;
}

效果见下:

04 随机方块过度

float smoothness = 0.5; // 0-1

float rand (vec2 co) {
  return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
const float tranSize = 10.;

vec4 RandomTransition(vec4 color,vec4 mixcolor, vec2 uv, float progression) {
  float r = rand(floor(vec2(tranSize) * uv));
  float m = smoothstep(0.0, -smoothness, r - (progression * (1.0 + smoothness)));
  color=  mix(color, mixcolor, m);
  return color;
}

效果见下:

05 规则方块过度

这个效果来自 shadertoy

#include <builtin/uniforms/cc-global>

const float tranSize = 32.;

vec4 BoxTransition(vec4 color,vec4 mixcolor, vec2 uv, float progression) {
  vec2 fragCoord = gl_FragCoord.xy;
  vec2 blockPos = vec2(progression) * cc_screenSize.xy;
  vec2 p = ceil(fragCoord / tranSize) * tranSize; 
  float progress = (p.x + p.y) / (blockPos.x + blockPos.y);
  vec2 v = abs(fragCoord - p + vec2(tranSize/2.));
  if (max(v.x, v.y) * progress < tranSize/2.) {
      color = mixcolor;
  }
  return color;
}

效果见下:

06 棱形过度

#include <builtin/uniforms/cc-global>

const float tranSize = 32.;

vec4 SideTransition(vec4 color,vec4 mixcolor, vec2 uv, float progression) {
  uv.x = 1.0 - uv.x;
  float xFraction = fract(gl_FragCoord.x / tranSize);
  float yFraction = fract(gl_FragCoord.y / tranSize);
  
  float xDistance = abs(xFraction - 0.5);
  float yDistance = abs(yFraction - 0.5);

  if (xDistance + yDistance + uv.x + uv.y < progression * 4.0) {
      color = mixcolor;
  }
  return color;
}

效果演示:

07 燃烧转场

注意:此效果由于未使用第二张图,因此可以合图

float fr(vec2 c, float seed) 
{
return fract(43.0 * sin(c.x + 7.0 * c.y) * seed);
}

float fn(vec2 p, float seed)
{
    vec2 i = floor(p), w = p - i, j = vec2(1.0, 0.0);
    w = w * w * (3.0 - w - w);
    return mix(mix(fr(i, seed), fr(i + j, seed), w.x), mix(fr(i + j.yx, seed), fr(i + 1.0, seed), w.x), w.y);
}

float fa(vec2 p, float seed) 
{
    float m = 0.0, f = 2.0;
    for (int i = 0; i < 6; i++) {
    m += fn(f * p, seed) / f; 
    f += f;
    }
    return m;
}
vec4 BurnOut(vec4 MainColor, vec2 UV, float Intensity) 
{
    float t = fract(Intensity * 0.9999);
    float cc = smoothstep(t / 1.2, t + 0.1, fa(3.5 * UV, 1.));
    vec4 c = vec4(cc);
    c = MainColor * c;
    c.r = mix(c.r, c.r * 15.0 * (1.0 - c.a) * 8.0, Intensity);
    c.g = mix(c.g, c.g * 10.0 * (1.0 - c.a) * 4.0, Intensity);
    c.b = mix(c.b, c.b * 5.0 * (1.0 - c.a), Intensity);
    return vec4(c.rgb, c.a);
}

演示效果:

你可以把这些效果,应用于画面截图、场景切换、战斗开始、卡牌溶解、抽奖系统等等。

希望上面的分享能够给大家的项目带来效果和开发效率上的提升,使大家可以用 Cocos Creator 更快地制作出更好的产品。

08 代码下载

上面的源码已在 Cocos Store 上免费开源!

今天的分享就到这里,快去下载吧!点击阅读原文可直达源码页面。


文章引用微信公众号"COCOS",如有侵权,请联系管理员删除!

博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。