版本说明

  • cocos creator 1.x shader 没有经过包装,可以直接定义shader,替换 sprite 原来的 shader,可以参考之前博客
  • cocos creator 2.x 引入了材质系统,使用 shader 必须通过材质,这里介绍下如何使用自定义 shader;
  • 2.1.2 版本编辑器中开放了实验版材质和shader,如图:
    在这里插入图片描述

流程

  1. 如上图,新建一个shader,即Effect,然后再新建一个材质 Material;
  2. 选中新建的材质,将材质的effect设为刚刚新建的 shader,如图:在这里插入图片描述
  3. 使用文本编辑器打开刚刚新建的 shader,可以看到有三大部分内容:
%{
......
}%

%%  vs  {
......
}

%% fs {
......
}

其中 vs 对应的就是顶点着色器,fs 对应片段着色器,定义shader时,修改这两部分内容即可。

  1. 最后,就是修改 sprite 的材质,提供一个工具,如下:
let MaterialUtils = {
    customCache: {}, // 保存自定义材质,避免重复加载
    MAT: {
        // build in
        DEFAULT: {
            custom: false,
            name: "2d-sprite",
        },
        GRAY: {
            custom: false,
            name: "2d-gray-sprite"
        },
		// custom
        TIME: {
            custom: true,
            name: "MaterialTime",
        },
        OVERLAY: {
            custom: true,
            name: "MaterialOverlay",
        },
    },
};

MaterialUtils.getMaterial = function(sp, matCfg, cb) {
    if (matCfg.custom) {
        let url = "material/" + matCfg.name;
        if (this.customCache[url]) {
            cb(false, this.customCache[url]);
            return;
        }

        cc.loader.loadRes(url, cc.Material, (err, asset) => {
            if (err) {
                cc.error(err);
                cb(err, null);
            }
            this.customCache[url] = asset;
            cb(false, asset);
        });
    } else {
        let mat = cc.Material.getInstantiatedBuiltinMaterial(matCfg.name, sp);
        cb(false, mat);
    }
};

MaterialUtils.useMaterial = function(sp, matCfg, cb) {
    MaterialUtils.getMaterial(sp, matCfg, (err, mat)=>{
        if (err) 
            return;
        mat.setProperty('texture', sp.spriteFrame.getTexture());
        sp.setMaterial(0, mat);
        sp.markForRender(true);
        cb(err, mat);
    });
};

module.exports = MaterialUtils;

可以看到,把自定义材质和系统内建材质分开处理的,因为内建材质默认就已经加载了,不需要我们另外去加载。使用非常简单,如:

const MaterialUtils = require("MaterialUtils");

cc.Class({
    extends: cc.Component,

    properties: {
        spCocoa: cc.Sprite,
    },

	onLoad() {
		MaterialUtils.useMaterial(this.spCocoa, MaterialUtils.MAT.OVERLAY, (err, mat) => {
	            if (err) {
                	return;
            	}
            	this.mat = mat;
        	});
		};
	});

最终效果如图:

在这里插入图片描述

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐