cesium 自定义材质
1.Entity
阅读以上官方文档,我们以Entity添加polyline线实体为例,可知自带的材质不能满足一些特殊需求,所以我们可以模仿MaterialProperty的具体实现代码,实现自定义的材质
1.1 ColorMaterialProperty源码
js
import Color from "../Core/Color.js";
import defined from "../Core/defined.js";
import Event from "../Core/Event.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
import Property from "./Property.js";
function ColorMaterialProperty(color) {
this._definitionChanged = new Event();
this._color = undefined;
this._colorSubscription = undefined;
this.color = color;
}
ColorMaterialProperty.prototype.getType = function (time) {
return "Color";
};
ColorMaterialProperty.prototype.getValue = function (time, result) {
if (!defined(result)) {
result = {};
}
result.color = Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color);
return result;
};
ColorMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof ColorMaterialProperty &&
Property.equals(this._color, other._color))
);
};
Object.defineProperties(ColorMaterialProperty.prototype, {
isConstant: {
get: function () {
return Property.isConstant(this._color);
},
},
definitionChanged: {
get: function () {
return this._definitionChanged;
},
},
color: createPropertyDescriptor("color"),
});
export default ColorMaterialProperty;
模仿这个源码写一个新的PolylineFlowMaterialProperty
js
import { Color, defaultValue, defined, Property, createPropertyDescriptor, Material, Event, Cartesian2 } from 'cesium';
const defaultColor = Color.TRANSPARENT;
import defaultImage from '../../../assets/images/effect/line-color-yellow.png';
const defaultForward = 1;
const defaultSpeed = 1;
const defaultRepeat = new Cartesian2(1.0, 1.0);
class PolylineFlowMaterialProperty {
constructor(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
this._definitionChanged = new Event();
// 定义材质变量
this._color = undefined;
this._colorSubscription = undefined;
this._image = undefined;
this._imageSubscription = undefined;
this._forward = undefined;
this._forwardSubscription = undefined;
this._speed = undefined;
this._speedSubscription = undefined;
this._repeat = undefined;
this._repeatSubscription = undefined;
// 变量初始化
this.color = options.color || defaultColor; //颜色
this.image = options.image || defaultImage; //材质图片
this.forward = options.forward || defaultForward;
this.speed = options.speed || defaultSpeed;
this.repeat = options.repeat || defaultRepeat;
}
// 材质类型
getType() {
return 'PolylineFlow';
}
// 这个方法在每次渲染时被调用,result的参数会传入glsl中。
getValue(time, result) {
if (!defined(result)) {
result = {};
}
result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color);
result.image = Property.getValueOrClonedDefault(this._image, time, defaultImage, result.image);
result.forward = Property.getValueOrClonedDefault(this._forward, time, defaultForward, result.forward);
result.speed = Property.getValueOrClonedDefault(this._speed, time, defaultSpeed, result.speed);
result.repeat = Property.getValueOrClonedDefault(this._repeat, time, defaultRepeat, result.repeat);
return result;
}
equals(other) {
return (
this === other ||
(other instanceof PolylineFlowMaterialProperty &&
Property.equals(this._color, other._color) &&
Property.equals(this._image, other._image) &&
Property.equals(this._forward, other._forward) &&
Property.equals(this._speed, other._speed) &&
Property.equals(this._repeat, other._repeat))
);
}
}
Object.defineProperties(PolylineFlowMaterialProperty.prototype, {
isConstant: {
get: function get() {
return (
Property.isConstant(this._color) &&
Property.isConstant(this._image) &&
Property.isConstant(this._forward) &&
Property.isConstant(this._speed) &&
Property.isConstant(this._repeat)
);
}
},
definitionChanged: {
get: function get() {
return this._definitionChanged;
}
},
color: createPropertyDescriptor('color'),
image: createPropertyDescriptor('image'),
forward: createPropertyDescriptor('forward'),
speed: createPropertyDescriptor('speed'),
repeat: createPropertyDescriptor('repeat')
});
export { PolylineFlowMaterialProperty };
1.2 Material添加材质
阅读cesium源码时发现,要想自定义材质生效,还要再Material中添加绑定材质
Material中fabric的详细信息可以查看官网的这篇文章 github.com/CesiumGS/ce...
所以我们增加如下材质代码
js
Material.PolylineFlowType = 'PolylineFlow';
Material._materialCache.addMaterial(Material.PolylineFlowType, {
fabric: {
type: Material.PolylineFlowType,
uniforms: {
// uniforms参数跟我们上面定义的参数以及getValue方法中返回的result对应,这里值是默认值
color: defaultColor,
image: defaultImage,
forward: defaultForward,
speed: defaultSpeed,
repeat: defaultRepeat
},
// source编写glsl,可以使用uniforms参数,值来自getValue方法的result
source: `czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 fragColor = texture(image, fract(vec2(st.s - speed*czm_frameNumber*0.005*forward, st.t)*repeat));
material.emission = fragColor.rgb;
material.alpha = fragColor.a;
return material;
}`
},
translucent: true
});
为了维护方便,可以将材质代码与PolylineFlowMaterialProperty放在一起,便于同步修改