Cesium材质——Material
简介:
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中,则直接报错。