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;
@ccclass
export 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;
}
}
获取源码请在公众号回复:
扫光
更多教程
请扫码关注