在论坛中有水友用多边形遮罩做了一个流光,这里分享一个用shader写的流光特效。
原理
将图片中指定区域的颜色亮度增大,或者加上颜色,然后在 update 中去更新这个高亮的区域。
代码
下面是 shader 内容, 关于 ShaderUtils 可以参考我之前的这篇博客。
顶点 shader:
module.exports =
`
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
varying vec2 v_texCoord;
varying vec4 v_fragmentColor;
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
`
片段 shader:
module.exports =
`
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord;
uniform float sys_time;
void main()
{
vec4 src_color = texture2D(CC_Texture0, v_texCoord).rgba;
float width = 0.2;
float start = sys_time * 1.2;
float strength = 0.02;
float offset = 0.2;
if( v_texCoord.x < (start - offset * v_texCoord.y) && v_texCoord.x > (start - offset * v_texCoord.y - width))
{
vec3 improve = strength * vec3(255, 255, 255);
vec3 result = improve * vec3( src_color.r, src_color.g, src_color.b);
gl_FragColor = vec4(result, src_color.a);
} else {
gl_FragColor = src_color;
}
}
`
在源文件中去更新 shader 中的 sys_time 变量,移动高亮区分的位置。
var ShaderUtils = require("ShaderUtils");
cc.Class({
extends: cc.Component,
properties: {
sp: cc.Sprite,
},
onLoad : function(){
this._time = 0;
this._sin = 0;
this._program = ShaderUtils.setShader(this.sp, "galaxy");
},
update (dt) {
this._time += 2 * dt;
this._program.use();
this._sin = Math.sin(this._time);
if(this._sin > 0.99){
this._sin = 0;
this._time = 0;
}
if(cc.sys.isNative){
var glProgram_state = cc.GLProgramState.getOrCreateWithGLProgram(this._program);
glProgram_state.setUniformFloat("sys_time", this._sin);
} else {
this._program.setUniformLocationWith1f(this._program.getUniformLocationForName("sys_time"), this._sin);
}
},
});
效果
上面的代码是 1.0X上的,2.X API 已修改