Laya2.4.0 2d Shader

开发工具 layabox2.4.0
由于最近项目上需要使用到消融的效果,网上查了各种资料。总算是用shader做出来了
最终效果:

在这里插入图片描述

//顶点着色器   直接使用的是laya官方自带的
var vs: string = `
        attribute vec4 posuv;
        attribute vec4 attribColor;
        attribute vec4 attribFlags;
        attribute vec4 clipDir;
        attribute vec2 clipRect;
        uniform vec4 clipMatDir;
        uniform vec2 clipMatPos;
        varying vec2 cliped;
        uniform vec2 size;
        uniform vec2 clipOff;
        #ifdef WORLDMAT
            uniform mat4 mmat;
        #endif
        #ifdef MVP3D
            uniform mat4 u_MvpMatrix;
        #endif
        varying vec4 v_texcoordAlpha;
        varying vec4 v_color;
        varying float v_useTex;
        void main() {
            vec4 pos = vec4(posuv.xy,0.,1.);
            #ifdef WORLDMAT
                pos=mmat*pos;
            #endif
            vec4 pos1  =vec4((pos.x/size.x-0.5)*2.0,(0.5-pos.y/size.y)*2.0,0.,1.0);
            #ifdef MVP3D
                gl_Position=u_MvpMatrix*pos1;
            #else
                gl_Position=pos1;
            #endif
            v_texcoordAlpha.xy = posuv.zw;
            v_texcoordAlpha.z = attribColor.a/255.0;
            v_color = attribColor/255.0;
            v_color.xyz*=v_color.w;
            v_useTex = attribFlags.r/255.0;
            float clipw = length(clipMatDir.xy);
            float cliph = length(clipMatDir.zw);
            vec2 clpos = clipMatPos.xy;
            #ifdef WORLDMAT
            if(clipOff[0]>0.0){
                clpos.x+=mmat[3].x;
                clpos.y+=mmat[3].y;
            }
            #endif
            vec2 clippos = pos.xy - clpos;

            if(clipw>20000. && cliph>20000.)
                cliped = vec2(0.5,0.5);
            else {
                cliped=vec2( dot(clippos,clipMatDir.xy)/clipw/clipw, dot(clippos,clipMatDir.zw)/cliph/cliph);
            }
        }
    `
//片元着色器  一个简单的功能 根据噪图 过滤掉低于阈值的颜色
var ps: string = `
        precision mediump float;
        varying vec2 v_texcoord;
        varying vec4 v_color;
        uniform sampler2D texture;
        uniform sampler2D u_NoiseTex;
        //消融阈值  0 - 1
        uniform float u_DissolveThreshold;

        varying vec4 v_texcoordAlpha;

        void main(){
            vec4 noiseTexValue = texture2D(u_NoiseTex, v_texcoordAlpha.xy);
            if (noiseTexValue.r < u_DissolveThreshold)
            {
                discard;
            }
            
            gl_FragColor = texture2D(texture, v_texcoordAlpha.xy);
        }
    `;

//需要继承精灵
export default class DissolveSurfaceSprite extends Laya.Sprite {
    private shaderValue: Laya.Value2D;
    //定义一个shaderid  用于laya在查找shader 时使用   
    static DissolveSurfaceSaveName: number = 9999;

    tex: Laya.Texture2D;

    constructor() {
        super();
        this.init();
    }

    public init(): void {
        this.shaderValue = new Laya.Value2D(DissolveSurfaceSprite.DissolveSurfaceSaveName, DissolveSurfaceSprite.DissolveSurfaceSaveName);
//重要的一步  将渲染设置为自定义
        this.customRenderEnable = true;

        this.shaderValue.shader = new Laya.Shader2X(vs, ps, DissolveSurfaceSprite.DissolveSurfaceSaveName);
    }

    public setTexture(t: Laya.Texture2D) {
        (this.tex as any) = t;
    }

    /**
     * 设置噪图纹理
     * @param t 
     */
    public setNoiseTexture(t: Laya.Texture2D) {
    //这里的名字是在shader里 定义好的。
        this.shaderValue['u_NoiseTex'] = t;
    }

    public setNoiseTexSkin(skin: string) {
        Laya.Texture2D.load(skin, new Laya.Handler(this, (tex) => {
            this.shaderValue['u_NoiseTex'] = tex._getSource();
        }));
    }
    /**
     * 设置消融范围  0 是原图  1 是消失完成
     * @param t 
     */
    public setDissolveThreshold(t) {
        this.shaderValue['u_DissolveThreshold'] = t;
    }

	// 自定义渲染提交
    public customRender(context: laya.resource.Context, x: number, y: number) {
    	//这一步很重要 
        context.drawTarget(this.tex as any, x, y, this.tex.width, this.tex.height, null, this.shaderValue);
    }
}


// 重要的步骤都已经做完了   只需要在使用的地方调用就行了

	//加载一个图片
        Laya.loader.load("res/layabox.png", Laya.Handler.create(this, () => {
            var texture: Laya.Texture2D = Laya.Loader.getRes("res/layabox.png");
            var spe: DissolveSurfaceSprite = new DissolveSurfaceSprite();
            spe.setTexture(texture);
            //设置噪图路径
            spe.setNoiseTexSkin('timg.jpg');
            spe.setDissolveThreshold(0);
            spe.x = Laya.stage.width / 2 - texture.width / 2;
            spe.y = Laya.stage.height / 2 - texture.height / 2;
            Laya.stage.addChild(spe);
            this.slider.on(Laya.Event.CHANGE, this, () => {
            	//修改显示
                spe.setDissolveThreshold(this.slider.value);
            })
        }));


知道流程后就简单很多了 最难的就是如何将shader和精灵结合在一起。也就是代码里的customRender 这一步

第一次写 比较简陋 请多多包含

别的坑暂时还没有踩 不过消融的效果还是满足了。各种炫酷的效果就需要会shader的大大写了。

//还需要在修改一下库文件
laya.core.js 

在这里插入图片描述

clear() {
            if(this.subID > ShaderDefines2D.SHADERDEFINE_FSHIGHPRECISION){
                this.defines._value = this.subID;
            }else{
                this.defines._value = this.subID + (ILaya.WebGL.shaderHighPrecision ? ShaderDefines2D.SHADERDEFINE_FSHIGHPRECISION : 0);
            }
            this.clipOff[0] = 0;
        }

代码中使用到的噪图 就是spe.setNoiseTexSkin(‘timg.jpg’); 这句
在这里插入图片描述

  • 1
    点赞
  • 7
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页

打赏

笙尽缘无

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者