Cesium实战 - 实现大气云层效果

news2024/12/26 20:45:19

Cesium实战 - 实现大气云层效果

  • Cesium 实现大气云层效果
    • 主要思路
    • 核心代码
    • 在线示例

Cesium 实现大气云层效果

在实际开发中,一般会有天气的效果,雨雪雾比较常见,相关的博客也很多,但是关于云层的天气效果还是比较少,而官方只有云朵效果,没有云层,本文介绍一下大气云层的效果

本文包括主要思路、核心代码和在线示例三部分。


主要思路

1. 添加矩形带有高度的矩形包裹地球。

实现思路也比较简单:既然是大气云层效果,那么必然是覆盖在地球之上的,开始想着使用球体来实现地球覆盖效果。

但是经过尝试,发现不太合适,需要将球心设置在地心,半径大于地球半径,不合理,于是放弃。

后来相当,地球范围无非是 [-180, -90, 180, 90],那么在地球上覆盖一个矩形(Rectangle)应该就可以。

尝试之后,发现非常完美;大气云层应该有高度,给矩形设置高度即可。

2. 给矩形设置动态效果,使云层动起来。

添加矩形之后,添加图片材质,虽然看起来是云层,但是云层并没有动,看起来不太合理。

于是,通过着色器给图片材质增加了一个动态效果,这样看起来云层是动态的,比较切近实际。

在这里插入图片描述


核心代码

1. 初始化以及参数。

// 初始化地球
const viewer = new Cesium.Viewer("cesiumContainer");
const entities = viewer.entities;

// 云层图片
const image = 'https://openlayers.vip/examples/resources/earth_cloud.png';

// 云层颜色
const color = new Cesium.Color(1.0, 1.0, 1.0, 1);

// 用于计算云层速度
const time = 20;

// 图片材质
const imageMaterial = new Cesium.ImageMaterialProperty({
  image: image
});

2. 创建矩形实体对象。

// 创建矩形实体
const entity = entities.add({
  rectangle: {
    coordinates: Cesium.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
    material: imageMaterial,
  },
});

2. 创建动态效果。

// 动态云层效果类
function CloudEffectMaterialProperty() {
  
    this._definitionChanged = new Cesium.Event();
  
  	// 速度
    this.speed = 200;
    // 颜色
    this.color = color;
    // 图层
    this._image = image;
    // 时间
    this.time = time;

	// 计算持续时间
    const durationDefault = 100000;
    this.duration = 100 / this.speed * durationDefault;
  
    this._time = new Date().getTime();
  
}
// 定义属性
Object.defineProperties(CloudEffectMaterialProperty.prototype, {
    isConstant: {
        get: function() {
            return false;
        }
    },
    definitionChanged: {
        get: function() {
            return this._definitionChanged;
        }
    },
    color: Cesium.createPropertyDescriptor('color')
});

CloudEffectMaterialProperty.prototype.getType = function(time) {
    return 'CloudEffect';
};
CloudEffectMaterialProperty.prototype.getValue = function(time, result) {
        if (!Cesium.defined(result)) {
            result = {};
        }
        result.color = Cesium.Property.getValueOrClonedDefault(
            this._color, time, Cesium.Color.WHITE, result.color);
        result.time = ((new Date().getTime() - this._time) % this.duration) / this.duration;
        return result;
};
CloudEffectMaterialProperty.prototype.equals = function(other) {
            return (this === other ||
                (other instanceof CloudEffectMaterialProperty &&
                    Cesium.Property.equals(this._color, other._color) &&
                    Cesium.Property.equals(this.speed, other.speed)));
}
;

Cesium.Material.CloudEffectType = 'CloudEffect';
Cesium.Material.CloudEffectImage = image;
Cesium.Material.CloudEffectColor = color;
// 着色器代码
Cesium.Material.CloudEffectSource = `
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 = color.rgb  ;
                     return material;
}
`;

// 添加着色器
Cesium.Material._materialCache.addMaterial(Cesium.Material.CloudEffectType, {
    fabric: {
        type: Cesium.Material.CloudEffectType,
        uniforms: {
            color: Cesium.Material.CloudEffectColor,
            image: Cesium.Material.CloudEffectImage,
            constantSpeed: constantSpeed,
            time: time
        },
        source: Cesium.Material.CloudEffectSource
    },
    translucent: function(material) {
        return true;
    }
});

viewer.zoomTo(viewer.entities);


Sandcastle.addToolbarButton("开启动态云层", function () {
  alert('动态云层!');
  entity.rectangle.height = 0;
  entity.rectangle.extrudedHeight = 100000;
  entity.rectangle.material = new CloudEffectMaterialProperty();
});


Sandcastle.addToolbarButton("开启静态云层", function () {
  alert('静态云层!');
  entity.rectangle.height = undefined;
  entity.rectangle.extrudedHeight = undefined;
  entity.rectangle.material = imageMaterial;
});


在线示例

示例中展示了, 三维地图大气云层效果

Cesium 沙盒示例

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/592464.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【调峰】储能辅助电力系统调峰的容量需求研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

经典神经网络(6)ResNet及其在Fashion-MNIST数据集上的应用

经典神经网络(6)ResNet及其在Fashion-MNIST数据集上的应用 1 ResNet的简述 ResNet 提出了一种残差学习框架来解决网络退化问题,从而训练更深的网络。这种框架可以结合已有的各种网络结构,充分发挥二者的优势。 ResNet以三种方式挑战了传统的神经网络架…

【LeetCode】342. 4的幂

342. 4的幂(简单) 方法一:二进制 思路 首先考虑一个数字是不是 2 的整数次方:如果一个数字 n 是 2 的整数次方,那么它的二进制一定是 0...010...0 这样的形式,将它和 -n 按位与的结果一定是它本身。如果 …

前沿质谱应用沙龙分享会暨苏州百趣落成仪式即将开幕!

质谱作为一项医学检验新技术,凭借高特异性、高灵敏度、多指标检测等优势,成为了体外诊断领域最富生命力的新技术之一。目前质谱技术能够准确的测定多种生物小分子代谢物,且质谱在大分子物质例如蛋白质方面也应用的非常广泛。目前,…

要电脑重装系统装在哪个盘最好

在进行电脑重装系统时,选择一个合适的系统安装盘是非常重要的。本文将为您介绍如何选择最佳的系统安装盘,以确保系统性能和稳定性的最佳表现。 工具/原料: 系统版本:windows系统 品牌型号:华硕VivoBook14 软件版本…

张小龙发明了小程序,是否意味着失败?

今天微信小程序上线,从开发到上线仅仅用了四天时间,这是一个了不起的成就。 小程序诞生以来,一直存在着一种声音:它是张小龙“伟大的发明”,是微信“伟大的创新”。然而,张小龙在小程序发布会上宣布&#…

Spark SQL概述、数据帧与数据集

文章目录 一、准备工作1、准备数据文件2、启动Spark Shell 二、加载数据为Dataset1、读文件得数据集 三、给数据集添加元数据信息1、定义学生样例类2、导入隐式转换3、将数据集转换成学生数据集4、对学生数据集进行操作(1)显示数据集内容(2&a…

认识熟悉 Stable Diffusion(SD)基本参数

界面样式 界面参数 界面参数说明prompt希望生成的图片的描述negative prompt不希望在图片中出现的描述Batch size每次生成的图片个数Width图片宽度Height图片高度 这里需要注意的就是尺寸,尺寸并非越大越好,需要根据自己的配置和需求适当调整&#xff…

node.js+vue学生读书笔记共享分享系统

从上面的描述中可以基本可以实现软件的功能: 1、开发实现读书笔记共享平台的整个系统程序; 2、管理员;首页、个人中心、用户管理、笔记分享管理、个人笔记管理、管理员管理、交流互动、系统管理等。 3、用户:首页、个人中心、笔记分享管理、个人笔记管理、我的收藏管理。 4、前…

Window10配置Maven详细教程

文章目录 一、Maven概述二、Maven下载三、配置Maven环境变量四、查看Maven是否配置成功五、为Maven配置本地仓库以及指定远程仓库5.1 Maven构件搜索顺序5.2 Maven配置本地仓库5.3 Maven指定远程仓库 一、Maven概述 Maven是专门管理和构建Java项目的工具,Maven的主要…

Linux nohup-后台挂起运行程序神器

一. 场景描述 天黑了,我得离开实验室去吃饭了。为了环保,我必须关闭电脑,减少不必要的浪费!正常情况下当我关闭终端或电脑时,上面运行的任务代码即会自动停止,但我依旧希望保持代码的正常运行,此…

Android 更新后跑不起来?快来适配 AGP8 和 Flamingo/JDK 17

随着 Android Studio Flamingo 正式版的发布,AGP 8(Android Gradle Plugin 8)也正式进入大家的视野,这次 AGP 8 相关更新属于「断代式」更新,同时如果想体验 AGP 8,就需要升级到 Android Studio Flamingo 版…

揭秘速卖通卖家成功的绝佳秘籍,助您打造畅销店铺!

在竞争激烈的速卖通市场中,如何让您的店铺脱颖而出并实现畅销?林哥今天就跟大家讲一讲一些成功速卖通卖家的绝佳秘籍,帮助您引导高流量和高转化率,成就一个畅销的店铺。 ​一、精确定位目标受众 成功的速卖通店铺离不开精确的目标…

自动生成作文的软件有哪些?盘点五种自动生成作文软件

写作是一项需要花费大量时间和精力的任务,而自动生成作文的软件可以帮助我们节省大量的时间。这些软件通过分析和归纳大量的素材和语言模型,能够快速生成高质量的文章。相比于传统的写作方式,使用自动生成作文软件可以更快地完成文章&#xf…

一套完整的客户管理系统应该包含哪些模块呢?

一套完整的客户管理系统应该包含哪些模块呢? 想要弄清楚一个完整的客户管理系统应该具备哪些功能,首先得清楚系统使用者、使用场景以及主要功能这三个因素。 以我们公司为例: 主要使用者:运营人员、市场人员、产品人员。主要目…

Android Settings中Preference的理解以及使用

Preference 是Android App 中重要的控件之一,Settings 模块大部分都是通过 Preference 实现 优点: Preference 可以自动显示我们上次设置的数据,Android提供preference这个键值对的方式来处理这种情况,自动保存这些数据&#xff…

链接生成二维码怎么弄?这些制作方法分享给大家

在现代社会中,链接生成二维码已经成为了一个非常实用的工具。通过将链接转换为二维码,我们可以将它们轻松地分享给朋友、家人或同事,而无需手动输入URL或复制粘贴。这使得信息的传播变得更加快捷和高效。例如,你正在计划一个聚会&…

Spring第三方bean管理

文章目录 1.第三方bean管理1.1 Bean1.2 小结 2.第三方bean依赖注入2.1 简单类型:成员变量2.2 引用类型:方法形参2.3 小结 3.总结 1.第三方bean管理 1.1 Bean 首先看一下目录结构,APP里面就初始化了SpringConfig文件 SpringConifg中就一句话…

【vue】8个非常实用的Vue自定义指令:

文章目录 一、批量注册指令,新建 directives/index.js 文件二、在 main.js 引入并调用【1】v-copy【2】v-longpress【3】v-debounce【4】v-emoji【5】v-LazyLoad【6】v-permission【7】vue-waterMarker【8】v-draggable 复制粘贴指令 v-copy 长按指令 v-longpress 输…

JUnit单元测试之旅

目录 1. 什么是单元测试和JUnit2. JUnit入门与基本注解2.1测试类的定义:2.2 生命周期注解:2.3断言注解:2.4 参数化单参数多参数通过方法获取参数 2.5 测试套件 三.用到的依赖包 1. 什么是单元测试和JUnit 单元测试(Unit Testing)是对软件中的最小可测试单元进行检查和验证。它…