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的值,至此,就实现完了动态扭曲的效果。

相关推荐
LcGero8 天前
TypeScript 快速上手:泛型与工具类型
typescript·cocos creator·游戏开发
LcGero9 天前
Cocos Creator 3.x 高维护性打字机对话系统设计与实现
cocos creator·打字机
LcGero9 天前
Cocos Creator 三端接入穿山甲 SDK
sdk·cocos creator·穿山甲
LcGero11 天前
Cocos Creator平台适配层框架设计
cocos creator·平台·框架设计
LcGero11 天前
Cocos Creator 业务与原生通信详解
android·ios·cocos creator·游戏开发·jsb
LcGero12 天前
TypeScript 快速上手:前言
typescript·cocos creator·游戏开发
Setsuna_F_Seiei13 天前
CocosCreator 游戏开发 - 多维度状态机架构设计与实现
前端·cocos creator·游戏开发
CodeCaptain3 个月前
cocoscreator 2.4.x 场景运行时的JS生命周期浅析
cocos creator·开发经验
CodeCaptain3 个月前
CocosCreator 3.8.x [.gitignore]文件内容,仅供参考
经验分享·cocos creator
VaJoy5 个月前
Cocos Creator Shader 入门 (21) —— 高斯模糊的高性能实现
前端·cocos creator