版本说明
- cocos creator 1.x shader 没有经过包装,可以直接定义shader,替换 sprite 原来的 shader,可以参考之前博客;
- cocos creator 2.x 引入了材质系统,使用 shader 必须通过材质,这里介绍下如何使用自定义 shader;
- 2.1.2 版本编辑器中开放了实验版材质和shader,如图:
流程
- 如上图,新建一个shader,即Effect,然后再新建一个材质 Material;
- 选中新建的材质,将材质的effect设为刚刚新建的 shader,如图:
- 使用文本编辑器打开刚刚新建的 shader,可以看到有三大部分内容:
%{
......
}%
%% vs {
......
}
%% fs {
......
}
其中 vs 对应的就是顶点着色器,fs 对应片段着色器,定义shader时,修改这两部分内容即可。
- 最后,就是修改 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;
});
};
});
最终效果如图: