简介:
Cesium.Material对象的目的,就是生成一段名称为czm_getMaterial的函数(示例代码如下),
这个czm_getMaterial函数,是shader代码,会被放到片元着色器中使用。
czm_material czm_getMaterial(czm_materialInput materialInput)
{...省略代码...return material;
}
Cesium.Material主要被MaterialProperty、Appearace这2个对象使用
1、创建自定义Material对象
创建一个自定义的material对象,主要是掌握fabric的结构就可以
fabric官方参考:
https://github.com/CesiumGS/cesium/wiki/Fabric
let materialPolylineFlow = new Cesium.Material({fabric: {type: "PolylineFlow",//自定义type类型uniforms: {color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),speed: 4,percent: 0.1,gradient: 0.4,},source: fs,//自定义的着色器,也就是定义czm_getMaterial函数的地方},translucent: function (material) {return true;},
});
2、Material的复用
上述代码定义了一个type(类型)名为“PolylineFlow”的Material实例对象。
里面包含4个uniform变量、一段自定义的shader代码、还有控制透明度的函数
问题:如果我想复用这个material对象,该怎么做?
比如,我想声明一个一模一样的material效果,只是color为蓝色Cesium.Color.BLUE
我该怎么做?
方案1:复制上述所有代码
只是修改color的值
let materialPolylineFlowBlue = new Cesium.Material({fabric: {//type: "PolylineFlowBlue",//不能和上面的PolylineFlow同名(也可以不写这个值)uniforms: {color: new Cesium.Color(0.0, 0.0, 1.0, 1.0),//只是这里的值变了,其他都没变speed: 4,percent: 0.1,gradient: 0.4,},source: fs,},translucent: function (material) {return true;},
});
这个可行,就是重复代码太多
方案2:封装一个工具类
解决重复代码,第1个想到的就是自己封装一个类,把公共代码集中到一块
class util{static getMaterialByType(strTypeName,options){if(strTypeName=="PolylineFlow"){let {color=new Cesium.Color(1.0, 0.0, 0.0, 1.0),speed=4,percent=0.1,gradient=0.4}=options;//——————下述代码和之前基本一致——————let material = new Cesium.Material({fabric: {//type: "PolylineFlowBlue",//没必要再传入这个参数了uniforms: {color: color,speed: speed,percent: percent,gradient: gradient,},source: fs,},translucent: function (material) {return true;},});//——————上述代码和之前基本一致——————}else if(strTypeName=="otherType"){//其他类型的Material}}
}
这个也可行!
获取一个蓝色的Material,代码如下
let materialBlue=util.getMaterialByType("PolylineFlow",{color:Cesium.Color.BLUE
})
方案3:Cesium自己的方案
通过Cesium.Material._materialCache.addMaterial来注册一个type类型的Material
Cesium.Material.PolylineFlowType = "PolylineFlow";
Cesium.Material._materialCache.addMaterial(Cesium.Material.PolylineFlowType,{fabric: {type: Cesium.Material.PolylineFlowType,uniforms: {color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),speed: 4,percent: 0.1,gradient: 0.4,},source: fs,},translucent: function (material) {return true;},},
);
之后,如果要复用这个PolylineFlow类型的Material
Cesium提供了2中方法
方法1:
let materialByNew = new Cesium.Material({fabric: {type: "PolylineFlow",uniforms: {color: new Cesium.Color(0.0, 0.0, 1.0, 1.0),},},
});
不推荐使用这个,假如type传入一个“非注册过”的material类型
不会报错,反而会进行“不完全注册”!
“不完全注册”是指
new Cesium.Material()的源码中,
虽然执行了Cesium.Material._materialCache.addMaterial()方法
但是,并不能复用!(可能是Cesium的bug)
方法2:
let materialByFrom = Cesium.Material.fromType("PolylineFlow", {color: new Cesium.Color(0.0, 1.0, 0.0, 1.0),
});
推荐使用这个,因为它就是一个纯粹的复用
fromType()的第1个参数,是要复用的material的type名称
如果传入的type值,不在materialCache中,则直接报错。