Shader实现扭曲效果

效果

分析

上图是一个动态扭曲效果。它展示了从原始纹理坐标空间开始的逐步过程,移动坐标原点到中心,根据距离和时间变量计算扭曲,以及最后的偏移纹理坐标和产生的动态扭曲效果。效果中体现了像素的移动,因此可以用Shader来处理,具体主要再片源着色器中处理。

  • 首先,将纹理坐标的原点移动到纹理的中心。
  • 计算每个点到中心的距离,并使用这个距离乘以时间变量来计算一个偏移角度,实现动态的扭曲效果。
  • 使用偏移角度计算偏移后的纹理坐标。
  • 根据偏移后的坐标,从纹理中取色,实现扭曲效果。

这里用Cocos Creator 2.4.12的版本创建Effect文件

typescript 复制代码
// 小南-扭曲黑洞

CCEffect %{
  techniques:
  - passes:
    - vert: vs
      frag: fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        texture: { value: white }
        time: { value: 0.0 }
}%

CCProgram vs %{
  precision highp float;

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


  in vec4 a_position;
  in vec2 a_uv0;
  out vec2 v_uv;
  void main() {
    gl_Position = cc_matViewProj * a_position;
    v_uv = a_uv0;
  }
}%

CCProgram fs %{
  precision highp float;
  #include <cc-global>
  #include <cc-local>
  in vec2 v_uv;
  uniform sampler2D texture;
  uniform c{
    // 用于控制扭曲的时间
    float time; 
  };
  
  void main() {
    // 将坐标原点移到纹理中心
    vec2 p = v_uv - 0.5; 
    float distanceToCenter = length(p);
    
    // 计算偏移角度,与距离成正比
    float offsetAngle = distanceToCenter * time;
    
    // 计算偏移后的坐标
    vec2 offsetCoord = vec2(
        p.x * cos(offsetAngle) - p.y * sin(offsetAngle),
        p.x * sin(offsetAngle) + p.y * cos(offsetAngle)
    );
    
    // 归一化坐标
    vec2 normalizedCoord = offsetCoord + 0.5;
    
    // 输出颜色
    gl_FragColor = texture2D(texture, normalizedCoord);
}
}%

在项目中通过传值time来控制扭曲的效果,代码如下:

typescript 复制代码
const { ccclass, property } = cc._decorator;
@ccclass
export default class distortEffect extends cc.Component {
    @property(cc.Node)
    bg: cc.Node = null;

    protected start(): void {
        this.schedule(this.onDistort.bind(this), 0.1, 360, 6);
    }
    private progress = 0;
    onDistort() {
        this.progress += 0.1;
        // 根据滑动的值设置材质
        this.bg.getComponent(cc.Sprite).getMaterial(0).setProperty('time', this.progress * 30);
    }
}

设置好背景图bg后,通过计时器来控制shader中time的值,至此,就实现完了动态扭曲的效果。

相关推荐
la_vie_est_belle1 个月前
《Cocos Creator游戏实战》非固定摇杆实现原理
游戏·cocos creator·游戏开发·cocos·非固定摇杆
布鲁克零三四四3 个月前
Cocos Creator导出obj文件用于后端寻路
cocos creator
烧仙草奶茶3 个月前
【cocos creator】输入框滑动条联动小组建
cocos creator·cocos-creator
烧仙草奶茶5 个月前
【cocos creator】2.x里,使用3D射线碰撞检测
3d·cocos creator·cocos-creator·2.x
仅此而已7295 个月前
Cocos Creator倒计时
游戏引擎·cocos creator
仅此而已7295 个月前
cocosUI多分辨率适配
游戏引擎·cocos creator·多分辩率适配
SilenceJude6 个月前
cocos creator 3学习记录01——如何替换图片
前端·cocos creator
GrimRaider7 个月前
[Cocos Creator] v3.8开发知识点记录(持续更新)
开发·cocos creator
S_clifftop7 个月前
cocos creator如何使用cryptojs加解密(及引入方法)
cocos creator·加密解密·cryptojs
平淡风云7 个月前
cocosCreator获取手机剪切板内容
java·智能手机·typescript·android studio·cocos creator