/** * 创建者:王成 * 操作系统:MAC * 创建日期:2022年12月29日 * 描述:动态扩散圆材质 */ class CircleMaterialProperty { /** * 构造方法 * @ignore 无需公开 * @param {JSON} options 配置项 * @param {Cesium.Viewer} options.viewer 着色器运行所需的视图 * @param {Cesium.Color} options.color [圆环的颜色,默认蓝色] 可选 * @param {Number} options.duration [循环时间 默认1000] 可选 * @param {Number} options.count [圆环的数量 可选 默认为1] */ constructor(options) { /* 着色器运行依赖的视图 */ this._viewer = options.viewer; /* 变更事件 */ this._definitionChanged = new Cesium.Event(); this._color = undefined; /* 扩算圆环的颜色 */ this.color = options.color || Cesium.Color.BLUE; /* 扩散圆环的数量 */ this.count = options.count || 1.0; /* 动态循环周期 */ this.duration = options.duration || 1000; /* 默认时间 */ this._time = (new Date()).getTime(); /* 材质类型名称 */ this._materialTypeName = 'jtCircleMaterial' /* 存储相关参数的属性 以便后期进行追踪修改 */ this._param = { color: this.color._value.toCssColorString(), duration: this.duration, count: this.count, } /* 将材质加入缓存 以便重复利用 */ Cesium.Material._materialCache.addMaterial(this._materialTypeName, { fabric: { type: this._materialTypeName, uniforms: { time: 0, color: new Cesium.Color(1.0, 0.0, 0.0, 0.5), count: 1.0, }, source: this._getCircleMaterial(), }, translucent: function(material) { /* 材质是否半透明 */ return true; } }); } /** * @ignore 无需公开 * 获取材质着色器Shader */ _getCircleMaterial() { let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" + "{\n" + " czm_material material = czm_getDefaultMaterial(materialInput);\n" + " material.diffuse = 1.5 * color.rgb;\n" + " vec2 st = materialInput.st;\n" + " vec3 str = materialInput.str;\n" + " float dis = distance(st, vec2(0.5, 0.5));\n" + " float per = fract(time);\n" + " if (abs(str.z) > 0.001)\n" + " {\n" + " //着色器渲染停止,不在绘制内容 \n" + " discard;\n" + " }\n" + " if (dis > 0.5)\n" + " {\n" + " //超出半径范围时,着色器渲染停止 \n" + " discard;\n" + " } else {\n" + " //把半径分成count份,每两份之间的间隔距离 \n" + " float perDis = 0.5 / count;\n" + " float disNum;\n" + " float bl = 0.0;\n" + " //循环,最多999个环 \n" + " for (int i = 0; i <= 999; i++)\n" + " {\n" + " //判断是否属于数量内的环 \n" + " if (float(i) <= count)\n" + " {\n" + " disNum = perDis * float(i) - dis + per / count;\n" + " if (disNum > 0.0)\n" + " {\n" + " if (disNum < perDis)\n" + " {\n" + " bl = 1.0 - disNum / perDis;\n" + " } else if (disNum - perDis < perDis) {\n" + " bl = 1.0 - abs(1.0 - disNum / perDis);\n" + " }\n" + " material.alpha = color.a * pow(bl, 3.0);\n" + " }\n" + " }\n" + " }\n" + " }\n" + " return material;\n" + "}\n"; return circleMaterial; } } /** * @ignore 无需公开 * 必须重写的方法 */ Object.assign(CircleMaterialProperty.prototype, { /** * 重新获取类型方法 * @ignore 无需公开 * @param {Cesium.JulianDate} time 时间 */ getType: function(time) { return this._materialTypeName; }, /** * 重写获取值方法 * @ignore 无需公开 * @param {Cesium.JulianDate} time * @param {JSON} result */ getValue: function(time, result) { if (!Cesium.defined(result)) { result = {}; } result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.BLUE, result .color); result.count = this.count; if (this.duration) { result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration; } this._viewer.scene.requestRender(); return result; }, /** * 重写对比函数 * @ignore 无需公开 * @param {Object} other 传入对比对象 */ equals: function(other) { return (this === other || (other instanceof CircleMaterialProperty && Cesium.Property.equals(this ._color, other._color))); } }) /** * 默认属性 */ Object.defineProperties(CircleMaterialProperty.prototype, { /** * 判断是否相等,返回false表示属性一直在变化中 * @ignore 无需公开 */ isConstant: { get: function() { return false; } }, /** * 事件变更 * @ignore 无需公开 */ definitionChanged: { get: function() { return this._definitionChanged; } }, /* 颜色属性 */ color: Cesium.createPropertyDescriptor('color') }) export default CircleMaterialProperty;