基于cocoscreater 2.0X使用shader 实现流光效果

首先是根据大神

https://blog.csdn.net/qq_15682489/article/details/84843304

https://blog.csdn.net/xufeng0991/article/details/79942979写的shader修改部分内容,

实现流光效果

 

基于cocoscreater 2.0X使用shader 实现流光效果_第1张图片

cocoscreater 2.0.8版本中新建一个helloworld项目

1.新建saoguang.frag.js

//saoguang.vert.js
module.exports = `
uniform mat4 viewProj;
attribute vec3 a_position;
attribute vec2 a_uv0;
varying vec2 uv0;
void main () {
    vec4 pos = viewProj * vec4(a_position, 1);
    gl_Position = pos;
    uv0 = a_uv0;
}`

2.新建saoguang.frag.js

//saoguang.trag.js
module.exports =
    `

uniform sampler2D texture;
varying vec2 uv0;
uniform float sys_time;
void main()
{
    vec4 src_color = texture2D(texture, uv0).rgba;
    float width = 0.2;
    float start = sys_time * 1.2;
    float strength = 0.02;
    float offset = 0.2;
    
    if( uv0.x < (start - offset * uv0.y) &&  uv0.x > (start - offset * uv0.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;
    }
}
`

3.新建shaderMaterial.js

const renderEngine = cc.renderer.renderEngine;
const Material = renderEngine.Material;

//ShaderMaterial.js
var material = cc.Class({
    extends: Material,

    callfunc (name, vert, frag, defines) {
        let renderer = cc.renderer;
        let lib = renderer._forward._programLib;
        !lib._templates[name] && lib.define(name, vert, frag, defines);
        this.init(name);
    },

    init(name) {
        let renderer = renderEngine.renderer;
        let gfx = renderEngine.gfx;

        let pass = new renderer.Pass(name);
        pass.setDepth(false, false);
        pass.setCullMode(gfx.CULL_NONE);
        pass.setBlend(
            gfx.BLEND_FUNC_ADD,
            gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA,
            gfx.BLEND_FUNC_ADD,
            gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA
        );
        
        let mainTech = new renderer.Technique(
            ['transparent'],
            [
                { name: 'texture', type: renderer.PARAM_TEXTURE_2D },
                { name: 'color', type: renderer.PARAM_COLOR4 },
                { name: 'pos', type: renderer.PARAM_FLOAT3 },
                { name: 'size', type: renderer.PARAM_FLOAT2 },
                { name: 'time', type: renderer.PARAM_FLOAT },
                { name: 'num', type: renderer.PARAM_FLOAT },
                { name: 'sys_time', type: renderer.PARAM_FLOAT }
            ],
            [pass]
        );

        this._texture = null;
        this._color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
        this._pos = { x: 0.0, y: 0.0, z: 0.0 };
        this._size = { x: 0.0, y: 0.0 };
        this._time = 0.0;
        this._num = 0.0;
        this._effect = this.effect = new renderer.Effect([mainTech], { 
            'color': this._color,
            'pos': this._pos,
            'size': this._size,
            'time': this._time,
            'num': this._num
        }, []);
        this._mainTech = mainTech;
    },

    setTexture(texture) {
        this._texture = texture;
        this._texture.update({ flipY: false, mipmap: false });
        this._effect.setProperty('texture', texture.getImpl());
        this._texIds['texture'] = texture.getId();
    },

    setColor(r, g, b, a) {
        this._color.r = r;
        this._color.g = g;
        this._color.b = b;
        this._color.a = a;
        this._effect.setProperty('color', this._color);
    },

    setPos(x, y, z) {
        this._pos.x = x;
        this._pos.y = y;
        this._pos.z = z;
        this._effect.setProperty('pos', this._pos);
    },

    setSize(x, y) {
        this._size.x = x;
        this._size.y = y;
        this._effect.setProperty('size', this._size);
    },

    setTime(time) {
        this._time = time;
        this._effect.setProperty('time', this._time);
    },

    setNum(num) {
        this._num = num;
        this._effect.setProperty('num', this._num);
    },
    setSysTime(num) {
        this._sys_time = num;
        this._effect.setProperty('sys_time', this._sys_time);
    },
});

module.exports = material;

4.新建soaguang.js

//saoguang.js
var util = {};
util.useShader = function (sprite, lab) {
    if (cc.game.renderType === cc.game.RENDER_TYPE_CANVAS) {
        console.warn('Shader not surpport for canvas');
        return;
    }
    if (!sprite || !sprite.spriteFrame || sprite.lab == lab) {
        return;
    }
    if (lab) {
        if (lab.vert == null || lab.frag == null) {
            console.warn('Shader not defined', lab);
            return;
        }
        cc.dynamicAtlasManager.enabled = false;

        let material = new ShaderMaterial();
        let name = lab.name ? lab.name : "None"
        material.callfunc(name, lab.vert, lab.frag, lab.defines || []);

        let texture = sprite.spriteFrame.getTexture();
        material.setTexture(texture);
        material.updateHash();

        sprite._material = material;
        sprite._renderData.material = material;
        sprite.lab = lab;
        return material;
    } else {
        // 这个就是直接变成灰色
        sprite.setState(1);
    }
};
cc.Class({
    extends: cc.Component,

    properties: {
      
    },

    onLoad: function () {
        this._time = 0;
        this._sin = 0;

        // this._program = ShaderUtils.setShader(this.sp, "galaxy");
    },
    start: function () {
        var name = "saoguang";
        var vert = require(cc.js.formatStr("%s.vert", name));
        var frag = require(cc.js.formatStr("%s.frag", name));
        var lab = {
            vert: vert,
            frag: frag,
            name: "galaxy"
        }
        let sprite = this.node.getComponent(cc.Sprite);
        let spriteFrame = sprite.spriteFrame;
        if (spriteFrame.textureLoaded()) {
            this._merial = this.changeMaterial(sprite, lab);
        }
    },
    changeMaterial: function (sprite, lab) {
        let material = util.useShader(sprite, lab);
        return material;
    },

    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;
        }
        this._merial.setSysTime(this._sin)
    },
});

将saoguang.js挂载到helloworld项目中到图片上运行即可。

你可能感兴趣的:(shader,流光)