版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ST_DarkMoon/article/details/77977867
Cocos Creator 实现按钮图标的流光特效(Shader)
cocos creator如何使用shader可以参考:
代码
流光效果脚本组件代码:
/*************************************************************
* 流光效果 shader挂件
* -----------------------------------------------------------
* author : saint | email : [email protected]
*
* create : 2017/09/12
* -----------------------------------------------------------
*
* CopyRight(C) 2017- | All Right Reserved
**************************************************************/
let vert_file = require("../ShaderFile/bright_vert.js");
let frag_file = require("../ShaderFile/bright_frag.js");
cc.Class({
extends : cc.Component,
properties : {
_time : 0.0,
},
onLoad : function(){
this._time = 0;
this._sin = 0;
this._use();
},
_use : function(){
this._program = new cc.GLProgram();
this._program.initWithVertexShaderByteArray( vert_file, frag_file);
// 添加程序属性至GLSL中
this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_POSITION, cc.macro.VERTEX_ATTRIB_POSITION);
this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_COLOR, cc.macro.VERTEX_ATTRIB_COLOR);
this._program.addAttribute(cc.macro.ATTRIBUTE_NAME_TEX_COORD, cc.macro.VERTEX_ATTRIB_TEX_COORDS);
this._program.link();
this._program.updateUniforms();
this._program.use();
this.updateGLParameters();
this._program.setUniformLocationWith1f(this._program.getUniformLocationForName("sys_time"),this._time);
this.setProgram(this.node._sgNode, this._program);
},
update : function( dt){
this._time += 2*dt;
if(this._program){
this._program.use();
this._sin = Math.sin(this._time);
if(this._sin > 0.99){
this._sin = 0;
this._time = 0;
}
this._program.setUniformLocationWith1f(this._program.getUniformLocationForName("sys_time"), this._sin);
}
},
updateGLParameters : function(){
this._time = Math.sin(Date.now());
},
setProgram : function(node, program){
node.setShaderProgram(program);
var children = node.children;
if (!children)
return;
for (var i = 0; i < children.length; i++)
{
this.setProgram(children[i], program);
}
},
});
对应的顶点着色器(bright_vert.js)代码:
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;
}
`
对应的片元着色器(bright_frag.js)代码:
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; //流光的起始x坐标
float strength = 0.01; //流光增亮强度 (调整该值改变流光的增亮强度)
float offset = 0.2; //偏移值 (调整该值改变流光的倾斜程度)
//if( start <= v_texCoord.x && v_texCoord.x <= (start + width))
if( v_texCoord.x < (start - offset * v_texCoord.y) && v_texCoord.x > (start - offset * v_texCoord.y - width))
{
float strength = 0.01;
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;
}
}
`
需要注意的是:
- 1.这是h5调用 如要在原生使用需要进行平台判定并进行差异操作.具体可参考上面的 [ Creator 中使用的 Shader效果控件 ]
- 2.如果挂载对象为一个具有button组件的节点.则当点击或者鼠标移动上去时.会使我们自定义的shader失效。这是button组件的内部封装导致的。在引擎源码CocosCreator\resources\engine\cocos2d\core\components\CCButton.js的_updateDisabledState函数中将将shader重置为默认shader的了,要使其生效可能需要对其进行修改。
_updateDisabledState: function () {
if(this._sprite) {
this._sprite._sgNode.setState(0); // setState(0)会重置shader。可将其注释或者其他操作。
}
if(this.enableAutoGrayEffect && this.transition !== Transition.COLOR) {
if(!(this.transition === Transition.SPRITE && this.disabledSprite)) {
if(this._sprite && !this.interactable) {
this._sprite._sgNode.setState(1);
}
}
}
}
(修改源码后可参考 [ cocos creator 修改源码教程并使浏览器预览生效(js) ]重新编译使得修改生效)