CreatorPrimer| CustomMaterial.js源码分析

1. 回顾


《ShaderHelper组件速递》一篇我们介绍了ShaderHelper组件的使用,以及如何定义一个shader程序并添加到ShaderHelper组件的program枚举属性中,这里我们再简单回顾下shader模板对象定义:

/**	
 * shader模板	
 **/	
const renderEngine = cc.renderer.renderEngine;	
const renderer = renderEngine.renderer;	
	
//定义一个shader对象	
const shader = {	
    //名字必须字段 	
    name: "xxx",	
    //着色器代码中需要与js交互的参数名字与数据类型	
    params: [	
        {name: 'yyy', type: renderer.PARAM_FLOAT},	
        {name: 'zzz', type: renderer.PARAM_FLOAT2}	
    ],	
    //着色器中使用到的define定义,非必要字段	
    defines: [],	
    //start回调,此可以初始化着色器中的参数	
    start(sprite, material) { ... },	
    //update每帧回调,如果是动态效果,可以在此设置Shader参数	
    update(sprite, material) { ... }, 	
    //vert顶点着色器代码,它是一个字符串	
    vert: '...',	
    //frag片元着色器	
    frag: `...`	
};	
//将shader对象添加到自定义材质中	
let CustomMaterial = require('CustomMaterial');	
CustomMaterial.addShader(shader);
  1. 最为基本的3个属性:name、vert、frag

  2. 如果要控制着色器中的参数变量需定义params字段

  3. 如果要控制define变量定义defines字段

  4. 如果要为param变量设置初始值可以在start回调函数中完成

  5. 如果需要每帧控制参数可以在update回调函数中完成

更多的使用细节请参看前一篇文章与github上的源码,今天分享的内容是ShaderHelper组件中的核心CustomMaterial源码分析。

640?wx_fmt=jpeg

2. CustomMaterial自定义材质系统


ShaderHelper组件只是对Cocos论坛Colin提供的CustomMaterial的调用,CustomMaterial又是对Cocos Creator引擎中的渲染引擎、材质系统API的运用,其中四个重要的对象:

Material(材质)、Effect(表现)、Technique(技术)、Pass(过程)

我们对CustomMaterial类的主要成员有个大概的认识,首先CustomMaterial继承自Cocos Creator引擎的Material类,同时它实现对Effect的实例化,看下面代码:

...	
var CustomMaterial = (function (Material$$1) {	
    ...	
    //继承Material	
    cc.js.extend(CustomMaterial, Material$$1);	
	
    //定义了三个属性effect、texture、color	
    var prototypeAccessors = { 	
        effect:  { configurable: true }, 	
        texture: { configurable: true }, 	
        color:   { configurable: true } 	
    };	
    ...	
    Object.defineProperties(CustomMaterial.prototype, prototypeAccessors);	
    ...	
}(Material));

上面我将干扰代码移除,基中最为关键的是effect属性的定义,我们看Effect是怎么实例化的:

//实现化Effect对象	
this._effect = new renderer.Effect(	
    [ mainTech ],	
    {},	
    defines, //第三个参数defines就是我们之前定义的shader.dfines字段	
);	
this._texture = null;	
this._color = { r: 1, g: 1, b: 1, a: 1 };	
...	
//定义effect\texutre\color的get方法	
prototypeAccessors.effect.get = function () {	
    return this._effect;	
};	
prototypeAccessors.texture.get = function () {	
    return this._texture;	
};	
prototypeAccessors.color.get = function () {	
    return this._color;	
};

上面代码实现化了_effect、texture、_color三个对象为内部私有成员,并为它们各自实现了get方法,使其可以被外部访问。

3. Effect的实例化


texture与color的初始化比较简,但Eeffect实例化需要三个参数,看下引擎源码:

//--------------CustomMaterail.js-----------------	
this._effect = new renderer.Effect(	
    [ mainTech ], 	
    {},  	
    defines, //defines就是我们之前定义的shader.dfines字段	
);	
	
//-----------------render-engine.js-----------------	
//看下Effect类构建函数参数	
var Effect = function Effect(techniques, properties, defines) {	
   ...	
};

Effect中三个数组分别是:techniques, properties, defines,其中defines就是我们前面shader对象中的defines。techniques是一个数组,我们接下来看CustomMaterial源码中是怎么创建它的。

4. Technique的实例化


Effect类的第一个参数需要Technique的数组,我们看Technique的创建:

//--------------------CustomMaterial.js-----------------------	
//定义了两个默认的参数:texture、color	
var techParams = [	
    { name: 'texture', type: renderer.PARAM_TEXTURE_2D },	
    { name: 'color', type: renderer.PARAM_COLOR4 }	
];	
//params就是之前定义的shader.params	
if (params) {	
    techParams = techParams.concat(params);	
}	
//实例化Technique,我们之前定义的params成了Technique的参数	
var mainTech = new renderer.Technique(	
    ['transparent'], //stages参数,暂时也没搞懂具体意思	
    techParams,     	
    [pass]	
);	
	
//--------------------render-engine.js-----------------------	
//Technique类的构建函数	
var Technique = function Technique(stages, parameters, passes, layer) {	
...	
}

Technique的构建函数需要4个参数,上面代码中给了前三个,其中techParams就是我们前面shader对象中定义的params字段,stages参数这里给的是['transparent']我暂时也没搞懂是什么意思,先暂时不管它。passes又是什么鬼呢?我看再看pass的创建过程。

5. Pass的实例化


创建Technique又需要一个passes数组,再看代码pass的实例化过程:

//我们之前定义的shader.name成了Pass的构造参数	
var pass = new renderer.Pass(shaderName);	
//下面的函数调用Shawn也不太了解,这里就不解释了,等弄明白了再回来	
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	
);

说话实Pass的实例化我也不太了解,通过字面意思猜测是设置材质相关的参数,参考了论坛中Panda提供的heartfelt工程,也是同样的写法。

6. 小结


本篇的内容有些烧脑,特别是对于像Shawn这种从来不怎么关心底层渲染的人来说在初次读源码完全是一脸的蒙逼。我们暂且不纠结细节,从整体上理清材质系统的框架结构,请看下图:

640?wx_fmt=png

Shawn也是在不断坚持的过程中结合Panda对Cocos Creator 2.x新渲染器的介绍,以及几次Colin热心的指导交流,后来又拜读了麒麟子大神的《Thinking in Unity3D:材质系统概览》一文,才让我对材质系统有了初步的理解,至此才有幸能初步读懂CustomMaterial源码,在此感谢以上大佬们!


如果觉得众,感谢

640?wx_fmt=jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值