cesium 自定义材质

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放在一起,便于同步修改

1.3 效果

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui