【CesiumJS材质】(2)图片横向移动

文章介绍了一个名为FlowPictureMaterialProperty的自定义材质类,用于在Cesium中创建流动效果的纹理图片。它通过GLSL着色器更新纹理坐标来实现时间依赖的动画,允许用户指定颜色、图片和持续时间。示例展示了如何在椭圆形状上应用此材质,实现图片随时间流动的效果。
摘要由CSDN通过智能技术生成

效果示例

在这里插入图片描述
在这里插入图片描述
要素说明:
在这里插入图片描述

代码

/*
 * @Date: 2023-07-19 11:15:22
 * @LastEditors: ReBeX  420659880@qq.com
 * @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,
// })

用例

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);

着色器

实现一个自定义材质的核心,是fabric对象的source属性,下面是本材质的基于GLSL语法的着色器代码:

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;
}

代码的主要功能是根据输入的 materialInput 创建一个材质对象 material,然后通过对纹理图像和颜色进行处理来修改该材质,并最终返回修改后的材质。以下是代码的解释:

  1. 创建默认材质:通过调用函数 czm_getDefaultMaterial(materialInput) 创建一个默认的材质对象,并将其赋值给变量 material
  2. 获取纹理坐标和颜色:通过 materialInput.st 获取纹理的坐标,并将其赋值给变量 st。然后,使用全局变量 timest.s 进行计算,得到一个新的纹理坐标 vec2(fract(st.s - time), st.t)。接着,使用该纹理坐标从 image 纹理中读取颜色值,并将其赋值给变量 colorImage
  3. 修改透明度和漫反射颜色:将 material.alpha 设置为 colorImage.a 乘以 color.a,表示材质的透明度是原始颜色和纹理图像的透明度乘积。然后,将 material.diffuse 设置为 colorImage.rgbcolor.rgb 相加后除以 2.0,表示材质的漫反射颜色是原始颜色和纹理图像的颜色均值。
  4. 返回修改后的材质:将修改后的材质 material 返回作为函数的结果。

其他

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用JavaScript实现图片横向滚动轮播图的示例代码: ```html <!DOCTYPE html> <html> <head> <style> * { margin: 0; padding: 0; } div { width: 400px; height: 320px; } #ads { border: 4px solid green; height: 320px; overflow: hidden; position: relative; } #ads li { list-style: none; height: 320px; } img { width: 400px; height: 320px; position: absolute; } </style> </head> <body> <div> <ul id="ads"> <li><img src="image1.jpg" alt="Image 1"></li> <li><img src="image2.jpg" alt="Image 2"></li> <li><img src="image3.jpg" alt="Image 3"></li> </ul> </div> <script> var ads = document.getElementById("ads"); var images = ads.getElementsByTagName("img"); var currentIndex = 0; function slideImages() { for (var i = 0; i < images.length; i++) { images[i].style.display = "none"; } currentIndex++; if (currentIndex >= images.length) { currentIndex = 0; } images[currentIndex].style.display = "block"; setTimeout(slideImages, 2000); // 每隔2秒切换图片 } slideImages(); </script> </body> </html> ``` 这段代码使用了JavaScript来实现图片横向滚动的轮播图效果。首先,通过获取`ads`元素和其中的`img`元素,然后定义一个变量`currentIndex`来表示当前显示的图片索引。`slideImages`函数用于切换图片,它会将所有图片隐藏,并将`currentIndex`加1,如果`currentIndex`超过了图片数量,则将其重置为0。然后,将当前图片显示出来,并使用`setTimeout`函数来定时调用`slideImages`函数,以实现自动切换图片的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值