Cocos Creator 实现按钮图标的流光特效(Shader)

来源:互联网 发布:女生一身淘宝爆款low 编辑:程序博客网 时间:2024/05/05 07:53

Cocos Creator 实现按钮图标的流光特效(Shader)

cocos creator如何使用shader可以参考:

  • [ Creator 中使用的 Shader效果控件 ]

代码

流光效果脚本组件代码:

/**************************************************************  流光效果 shader挂件*  -----------------------------------------------------------*  author : saint       |  email : 1332614620@qq.com**  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);        }    },    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_ESprecision mediump float;#endifvarying 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) ]重新编译使得修改生效)

原创粉丝点击