Cocos Creator - 2D扭曲Shader

前言

昨天刚办完离职手续,今天闲来无事,就分享一篇关于cocos shader中的扭曲(水波纹)特效的实现吧,话不多说,直接步入正题。

CocosCreator版本:2.4.2

效果

在这里插入图片描述

这个效果原理非常简单,就是对 texture 随机采样,当然,这个随机会有一定的约束,不能太随机,在当前uv坐标附近随机即可。也就是说对uv进行随机偏移。

在shader中没有内置的随机函数,要么自己写一个随机函数,要么通过采样噪声图拿到随机值。这里我们就采用第二种方法,简单而且性能也好。(在shader中严格说来应该叫噪声,有兴趣的可以自己去查阅相关的资料)

首先我们需要一张的噪声图:
在这里插入图片描述
在shader中添加noisetex 属性,用来接收噪声纹理,并在拖拽图片到属性面板:

在这里插入图片描述

有了噪声图,我们就可以轻松的得到所谓的随机值了,代码如下:

vec4 noise = vec4(1);
CCTexture(noisetex, v_uv0.xy, noise);

此时我们得到了噪声值,然后我们对 uv坐标进行偏移,最后在采样,代码如下:

vec2 uv_temp = v_uv0;
uv_temp += noise.xy;

vec4 o = vec4(1);
CCTexture(texture, uv_temp, o);

此时效果大致如下:
在这里插入图片描述

现在是一个静态的,然后我们怎么让它动起来呢?很简单,在采样噪声图的时候加上一个时间变量就可以了。如下:

CCTexture(noisetex, v_uv0.xy + v_time.x * speedFactor , noise);

v_time 是从顶点着色器 传递到 片元着色器的,内置变量为:cc_time,随着游戏运行不断增长。
此时我们就得到了一个动态的噪声值。
注意:纹理 Wrap Mode 需要设置为平铺模式 Repeat

在这里插入图片描述
此时运行游戏,我们就能看到一个动态扭曲的特效了。

至此完毕,最后附上完整shader源码

// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.  
/**
 扭曲 特效
 author: lichanglong
 create time:2020.8.11
 **/
CCEffect %{
  techniques:
  - passes:
    - vert: vs
      frag: fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        texture: { value: white }
        alphaThreshold: { value: 0.5 }
        # 噪声纹理
        noisetex: { value: white }
        speedFactor: {
          value: 0.1,
          editor: {
            tooltip: "速度",
            range: [0.0, 1.0],
          }
        }
        strengthFactor: {
          value: 0.1,
          editor: {
            tooltip: "强度",
            range: [-0.5, 0.5],
          }
        }
        isHorizontal: {
            value: 0,
            editor: {
              tooltip: "横向扭曲",
              range: [0.0, 1.0],
            }
        }
        isVertical: {
            value: 0,
            editor: {
              tooltip: "纵向扭曲",
              range: [0.0, 1.0],
            }
        }
}%


CCProgram vs %{
  precision highp float;

  #include <cc-global>
  #include <cc-local>

  in vec3 a_position;
  in vec4 a_color;
  out vec4 v_color;

  #if USE_TEXTURE
  in vec2 a_uv0;
  out vec2 v_uv0;
  #endif

  out vec4 v_time;

  void main () {
    vec4 pos = vec4(a_position, 1);

    #if CC_USE_MODEL
    pos = cc_matViewProj * cc_matWorld * pos;
    #else
    pos = cc_matViewProj * pos;
    #endif

    #if USE_TEXTURE
    v_uv0 = a_uv0;
    #endif
    v_color = a_color;

    v_time = cc_time;
    gl_Position = pos;
  }
}%


CCProgram fs %{
  precision highp float;
  
  #include <alpha-test>
  #include <texture>

  in vec4 v_color;

  #if USE_TEXTURE
  in vec2 v_uv0;
  uniform sampler2D texture;
  #endif

  #if USE_NOISETEX
  uniform sampler2D noisetex;
  #endif

  uniform Factor {
      float speedFactor;
      float strengthFactor;
      float isHorizontal;
      float isVertical;
  };

  in vec4 v_time;

  void main () {
    vec4 o = vec4(1);
    vec4 noise = vec4(1);

    vec2 uv_temp = v_uv0;

    // 采样噪声纹理
    #if USE_NOISETEX
      CCTexture(noisetex, v_uv0.xy + v_time.x * speedFactor , noise);
    #endif
      // 偏移uv
      // uv_temp += noise.xy * strengthFactor;
      float isH = step(0.1, isHorizontal);
      float isV = step(0.1, isVertical);

      uv_temp.x += noise.x * strengthFactor * isH;
      uv_temp.y += noise.x * strengthFactor * isV;

    #if USE_TEXTURE
      CCTexture(texture, uv_temp, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o);

    gl_FragColor = o;
  }
}%

最后

以上可能需要稍微懂点shader的同学才能理解,项目源码在我的 GitHub 能找到,不只是cocos中shader,还有关于Unity 和 WebGL相关的工程,喜欢的可以给个star,谢谢!

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值