cocos creator | 使用纹理实现扫光效果- 流光shader

​01

效果预览

02

实现原理

uv 坐标:

纹理的百分比坐标

在 creator 中,uv 坐标的原点在左上角,u轴向右,v轴向下,范围是 0-1

使用纹理坐标获取纹理颜色叫做采样(Sampling)

根据时间控制流光纹理的 uv 坐标,获取其 rgba,然后与目标纹理 uv 坐标的 rgba 叠加,实现流动的效果

03

实现步骤

1创建材质

在资源管理器面板合适的目录右键:

新建 Effect:

//扫光-纹理CCEffect %{
   
     techniques:  - passes:    - vert: vs      frag: fs      blendState:        targets:        - blend: true      rasterizerState:        cullMode: none      properties:        texture: { value: white }        u_fluxayTexture: { value: white }        u_time: { value: 0 }}%// Vertex Shader(顶点着色器) // 将顶点从模型空间坐标系统转化到屏幕空间坐标系统// 顶点着色器分为输入和输出两部分// 负责的功能是把输入的数据进行矩阵变换位置,计算光照公式生成逐顶点颜⾊,⽣成/变换纹理坐标// 并且把位置和纹理坐标这样的参数发送到片段着色器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    // 输入的纹理坐标    // UV坐标:原点在左上角,u轴是向右,v轴是向下,范围是0-1    in vec2 a_uv0;    // 输出的纹理坐标    out vec2 v_uv0;  #endif  void main () {
   
       mat4 mvp;        #if CC_USE_MODEL      mvp = cc_matViewProj * cc_matWorld;    #else      mvp = cc_matViewProj;    #endif    v_uv0 = a_uv0;    v_color = a_color;    gl_Position = mvp * vec4(a_position, 1);  }}%// Fragment Shader(片段着色器)// 片元着色器的作用是处理由光栅化阶段生成的每个片元,最终计算出每个像素的最终颜色(RGBA)CCProgram fs %{
   
     precision highp float;  #include <alpha-test>  #include <texture>    in vec4 v_color;  in vec2 v_uv0;  uniform sampler2D texture;  uniform sampler2D u_fluxayTexture;  //流光纹理  // 自定义属性  // 所有非 sampler 的 uniform 都必须以 UBO 形式声明  // UBO 成员声明类型和顺序有严格的校验机制,以排除 GL 标准下隐式布局对齐带来的内存消耗  uniform ARGS {
   
       float u_time;  };  void main () {
   
       vec4 o = vec4(1, 1, 1, 1);    #if USE_TEXTURE      // texture.inc 核心函数      // o = texture2D(texture, v_uv0);      // texture: 纹理,v_uv0: 纹理坐标,通过 GLSL 的内建函数 texture2D 来获取纹理上对应UV坐标的颜色(RGBA)      o = texture2D(texture, v_uv0);    #endif    // 纹理颜色和顶点颜色(节点颜色)叠加得到最终颜色    o *= v_color;    // alpha-test.inc 核心函数    // if (color.a < alphaThreshold) discard;    // discard:退出片段着色器,不执行后面的片段着色操作,片段也不会写入帧缓冲区    ALPHA_TEST(o);    // 在底图不透明的地方叠加流光纹理的颜色    if(o.a >= 1.0) {          // 根据时间控制流光纹理的UV      vec2 fluxayUV = vec2(v_uv0.x, v_uv0.y);      fluxayUV.x -= u_time - 1.0;      // 获取流光纹理上UV的颜色      vec4 fluxay = texture2D(u_fluxayTexture, fluxayUV);      // 叠加颜色      gl_FragColor = o + fluxay;    } else {
   
         gl_FragColor = o;    }  }}%

新建 Material,在其 属性检查器 的 Effect 下拉框中选择刚刚创建 Effect 选项,然后在纹理的位置拖入流光纹理,点击应用

然后将该材质拖入到 sprite 组件的材质位置

2编写脚本组件

接下来需要编写脚本组件,将时间传递给 effect

const { ccclass, property } = cc._decorator;@ccclassexport default class FluxayTexture extends cc.Component {
   
       private _speed: number = 1;    private _time: number = 0;    private _material: cc.MaterialVariant;    onLoad() {
   
           // 获取材质        this._material = this.node.getComponent(cc.Sprite).getMaterial(0);    }    update(dt) {
   
           if (this._time > 2) {
   
               this._time = 0;        }        this._material.setProperty("u_time", this._time);        this._time += dt * this._speed;    }}

获取源码请在公众号回复:

扫光

更多教程

请扫码关注

猜你喜欢

转载自blog.csdn.net/u010799737/article/details/118495279