[CesiumJS material] (2) Image horizontal movement

Effect example

insert image description here
insert image description here
Description of elements:
insert image description here

the code

/*
 * @Date: 2023-07-19 11:15:22
 * @LastEditors: ReBeX  [email protected]
 * @LastEditTime: 2023-07-28 12:08:58
 * @FilePath: \cesium-tyro-blog\src\utils\Material\FlowPictureMaterialProperty.js
 * @Description: 流动纹理/图片材质
 */
import * as Cesium from 'cesium'

export default class FlowPictureMaterialProperty {
    
    
  constructor(options) {
    
    
    this._definitionChanged = new Cesium.Event();
    this._color = undefined;
    this._colorSubscription = undefined;
    this.image = options.image;
    this.color = options.color;
    this.duration = options.duration;
    this._time = (new Date()).getTime();
  };

  get isConstant() {
    
    
    return false;
  }

  get definitionChanged() {
    
    
    return this._definitionChanged;
  }

  getType(time) {
    
    
    return Cesium.Material.FlowPictureMaterialType;
  }

  getValue(time, result) {
    
    
    if (!Cesium.defined(result)) {
    
    
      result = {
    
    };
    }
    result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
    result.color = Cesium.Property.getValueOrDefault(this._color, time, Cesium.Color.RED, result.color);
    // result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
    result.image = this.image;
    return result
  }

  equals(other) {
    
    
    return (this === other ||
      (other instanceof FlowPictureMaterialProperty &&
        Property.equals(this._color, other._color))
    )
  }
}


Object.defineProperties(FlowPictureMaterialProperty.prototype, {
    
    
  color: Cesium.createPropertyDescriptor('color'),
})

// Cesium.FlowPictureMaterialProperty = FlowPictureMaterialProperty;
Cesium.Material.FlowPictureMaterialProperty = 'FlowPictureMaterialProperty';
Cesium.Material.FlowPictureMaterialType = 'FlowPictureMaterialType';
Cesium.Material.FlowPictureMaterialSource =
  `
  czm_material czm_getMaterial(czm_materialInput materialInput)
  {
    czm_material material = czm_getDefaultMaterial(materialInput);
    vec2 st = materialInput.st;
    vec4 colorImage = texture(image, vec2(fract(st.s - time), st.t));
    material.alpha = colorImage.a * color.a;
    material.diffuse = (colorImage.rgb+color.rgb)/2.0;
    return material;
  }
`


Cesium.Material._materialCache.addMaterial(Cesium.Material.FlowPictureMaterialType, {
    
    
  fabric: {
    
    
    type: Cesium.Material.FlowPictureMaterialType,
    uniforms: {
    
    
      color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),
      time: 0,
      image: ''
    },
    source: Cesium.Material.FlowPictureMaterialSource
  },
  translucent: function (material) {
    
    
    return true;
  }
})
console.log('成功加载流动纹理/图片材质');


// ? 如何使用
// import FlowPictureMaterialProperty from '@/utils/Material/FlowPictureMaterialProperty.js'

// material: new FlowPictureMaterialProperty({
    
    
//   color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),
//   image: '/src/assets/images/cat.png',
//   duration: 3000,
// })

Example

import FlowPictureMaterialProperty from '@/utils/Material/FlowPictureMaterialProperty.js'
import {
    
     viewer } from '@/utils/createCesium.js' // 引入地图对象
import * as Cesium from 'cesium'

const ellipse = viewer.entities.add({
    
    
  position: Cesium.Cartesian3.fromDegrees(50, 50),
  ellipse: {
    
    
    semiMajorAxis: 150000.0, // 长半轴距离
    semiMinorAxis: 150000.0, // 短半轴距离
    material: new FlowPictureMaterialProperty({
    
    
      color: Cesium.Color.WHITE, // new Cesium.Color(1.0, 1.0, 1.0, 1.0),
      image: '/src/assets/images/redBar.png',
      duration: 1500,
    })
  }
});
viewer.zoomTo(ellipse);

shader

The core of implementing a custom material is the source attribute of the fabric object. The following is the shader code of this material based on GLSL syntax:

czm_material czm_getMaterial(czm_materialInput materialInput)
{
    
    
  czm_material material = czm_getDefaultMaterial(materialInput);
  vec2 st = materialInput.st;
  vec4 colorImage = texture(image, vec2(fract(st.s - time), st.t));
  material.alpha = colorImage.a * color.a;
  material.diffuse = (colorImage.rgb+color.rgb)/2.0;
  return material;
}

materialInputThe main function of the code is to create a material object based on the input material, then modify the material by manipulating the texture image and color, and finally return the modified material. Here is an explanation of the code:

  1. czm_getDefaultMaterial(materialInput)Create a default material: Create a default material object by calling a function and assign it to a variable material.
  2. Get texture coordinates and colors: materialInput.stGet texture coordinates by and assign them to variables st. Then, use the global variable timeto st.scalculate to get a new texture coordinate vec2(fract(st.s - time), st.t). Next, use that texture coordinate imageto read the color value from the texture and assign it to a variable colorImage.
  3. Modify transparency and diffuse color: set material.alphato colorImage.amultiplied by color.a, indicating that the transparency of the material is the product of the original color and the transparency of the texture image. Then, material.diffuseset to add colorImage.rgband color.rgbdivide by 2.0, indicating that the diffuse color of the material is the average of the original color and the color of the texture image.
  4. ReturnModifiedMaterial: Returns the modifiedMaterial materialas the result of the function.

other

insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/ReBeX/article/details/131977566