jjzjj

兔年首文迎新春-Cesium橘子洲烟花礼赞

夜郎king 2023-04-03 原文

兔年新春

今天是兔年大年初二,神州大地,在经历了疫情的三年后迎来开放的一个春节。大家都沉浸在欢乐幸福的春节气氛中。玉兔迎新春,祝福齐送到:白兔祝你身体安康,黑兔祝你薪水高涨,灰兔送你梦想如意,花兔愿你早日高升,公兔祈祷你名利双收,母兔称赞你家和万事兴,只有兔崽崽最淘气,鞭炮连连,让你欢乐一整年。祝各位技术同仁在新的一年里,发量比Bug多,他/她比最帅/最靓的明星更亮,RMB把钱包撑破。

一、橘子洲头

1、橘子洲与伟人

大家对《沁园春.长沙》想必都非常熟悉。词的内容,上阙为描写湘江、橘子洲、岳簏山生机盎然的秋景,下阙为怀念同学少年的生活,抒发救世济民的远大理想,洋溢着激流奋进的壮志和豪情。现在,诗词碑已成为橘洲景区的标志性景点之一。词中,橘子洲头、看万山红遍、层林尽染、万江碧透、百舸争流,描述的就是橘子洲头的景象。恰同学少年,风华正茂,书生意气,挥斥方遒。表达了伟人当时的远大理想和壮志豪情,每次登临岳麓山,到岳麓书院,于橘子洲头,感受到流传下来的气魄,因此,这山和水也便被赋予了精神。

2、橘子洲与烟花

作为旅游城市,橘子洲的烟花表演一直是以前很多来星城必须要进行的一项打卡活动,同时也是湖南烟花对外展示的一个窗口。当然,烟花燃放的污染物排放一直是人们关注的首个重点目标,而现在浏阳烟花也是不断的改进烟花燃放工艺,争取减少污染区的排放。而随着疫情的爆发,也加上对排污治理的整治,橘子洲烟花与人们的邂逅机会就越来越少,曾几何时,橘子洲烟花是一周一次,后面变成了逢重大活动才燃放,一般在一年4次左右。下面来几张曾经的橘子洲烟花的燃放盛况,供大家观赏吧,图片来源于网络供图(百家号影像湖南)。

3、绿色燃放

虽然现在难得遇到一次橘子洲头的烟花燃放,但作为技术人,可以充分利用WebGL技术,结合时空地理地图,地形数据来一场实时可见的烟花燃放盛况。在这里遇见岳麓山、遇见橘子洲头,山水洲城的盛宴。在本文中基于Cesium开源框架,采用开源WebGL技术,叠加全国影像地图(本地私有化),标签路网数据、地形数据,采用粒子系统,实现烟花燃放的效果。先来一张效果图开胃吧。

二、Cesium烟花实现

1、相关依赖

由于采用Cesium开源实现,因此基础的依赖于Cesium.js,感兴趣的朋友可以自行在github(cesium github)或者官方网站(cesium)上下载相关依赖。Cesium可以基于原生的html5和javascript来进行运行,也支持和现代流程框架React和Vue等前端框架进行集成开发。可以根据自己的技术栈来合理选型。

将下载之后的Cesium编译后的js文件复制到工程的Build目录下,如下所示:

在上一层的Documentation目录中是同版本对应的API文档,您可以直接打开html页面,这是最全的API介绍文档。

2、新建html页面

在cesiumdemo或者任意目录下新建fireworks2.html,关键代码如下所示:

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Use correct character set. -->
    <meta charset="utf-8" />
    <!-- Tell IE to use the latest, best version. -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <title>大展宏兔,大吉大利</title>
    <script src="Build/Cesium/Cesium.js"></script>
    <style>
      @import url(Build/Cesium/Widgets/widgets.css);
      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div id="cesiumContainer"></div>
  </body>
</html>

在上面的代码中通过引入Cesium.js,并且在页面中创建了一个div用于渲染展示cesium地球组件。但这是还未将cesium和页面元素进行绑定,也没有加载加载相应的底图和地形数据。

3、底图和地形数据加载

下面将通过UrlTemplateImageryProvider对象来进行Cesium的底图对象定义,示例代如下所示:

//加载影像底图
var imageryProvider = new Cesium.UrlTemplateImageryProvider({
    url: "http://localhost:8086/data/basemap_water/{z}/{x}/{y}.png",
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    fileExtension: 'png',
    minimumLevel: 1,
    maximumLevel: 16
});

var labelProvider = new Cesium.UrlTemplateImageryProvider({
    url: "http://localhost:8086/data/basemap_nowater/1-10label/{z}/{x}/{y}.png",
    tilingScheme: new Cesium.GeographicTilingScheme(),//投影方式为经纬度直投,否则路网不对
    fileExtension: 'png',
    minimumLevel: 1,
    maximumLevel: 10
 });
//加载本地地形数据
var terrainLayer = new Cesium.CesiumTerrainProvider({
    url: "http://localhost:8086/data/hunanterrain",
    // 请求照明
    requestVertexNormals: true,
    // 请求水波纹效果
    requestWaterMask: false
});

上面的代码定义了地形数据,同时使用如下的代码将地形数据、底图数据都添加到Cesium的视图对象中,并且将标签图层也添加到对象中。用于系统,同时将cesium的展示视角初始调整为橘子洲的经纬度坐标。

var viewer = new Cesium.Viewer('cesiumContainer',{
    imageryProvider:imageryProvider,
    terrainProvider: terrainLayer,
    baseLayerPicker:false,
    homeButton: true,
    baseLayerPicker: false,
    animation: false,
    timeline: false,
    navigationHelpButton: false,
    geocoder: false,
    sceneModePicker: false,
    shouldAnimate: true,
});

// 设置相机初始位置
var homeCameraView = {
        destination: Cesium.Cartesian3.fromDegrees(112.955074,28.16843,507.0480578185452),
            orientation: {
                heading:5.656571359006588,
                pitch: -0.28428181994862656,
                roll: 0
            },
        };

viewer.camera.setView(homeCameraView);

viewer.imageryLayers.addImageryProvider(labelProvider);
// 隐藏版权信息
viewer._cesiumWidget._creditContainer.style.display = "none";

viewer.scene.globe.enableLighting = false;//关闭光照

4、粒子系统

粒子系统是WebGL中的一个非常重要的组成部分,通过粒子系统可以实现很多的特效。粒子系统是一种模拟复杂物理效应的图形技术。粒子系统是小图片的集合,当放到一起观察它们时,会形成一个更复杂的“模糊”对象,例如火、烟雾、气候,或者烟火(fireworks)。通过使用例如初始位置、速度和寿命属性来指定单个粒子的行为,可以控制这些复杂的效果。这里推荐一篇介绍粒子系统比较简单同时讲解比较清楚的入门博客Cesium中文教程-粒子系统介绍(Introduction to Particle Systems)cesium粒子系统介绍,更多的关于粒子系统的说明,可以上WebGL知识去深入学习,这里不做特别深入的讲解(因为博主也学得不深)。本文结合代码来简要说明粒子系统的一些知识。

模拟图片源,粒子系统可以理解是多个小图片的集合整体渲染。所以可以基于外部图片的渲染,比如爆炸的效果,同时作为烟花的特效,这里采用模拟图片实现。关键代码如下:

let particleCanvas;

function getImage() {
  if (!Cesium.defined(particleCanvas)) {
        particleCanvas = document.createElement("canvas");
        particleCanvas.width = 30;
        particleCanvas.height = 30;
        const context2D = particleCanvas.getContext("2d");
        context2D.beginPath();
        context2D.arc(10, 10, 10, 0, Cesium.Math.TWO_PI, true);
        context2D.closePath();
        context2D.fillStyle = "rgb(255, 255, 255)";
        context2D.fill();
       }
   return particleCanvas;
}

粒子系统在Cesium被进行了简单封装,开发者通过API进行简单调用即可。

new Cesium.ParticleSystem({
    image: getImage(),
    startColor: color,
    endColor: color.withAlpha(0.0),
    particleLife: life,
    speed: 30.0,
    imageSize: particlePixelSize,
    emissionRate: 0,
    emitter: new Cesium.SphereEmitter(1.8),
    bursts: bursts,
    lifetime: lifetime,
    updateCallback: force,
    modelMatrix: modelMatrix,
    emitterModelMatrix: emitterModelMatrix,
   })
);

最后通过循环和一些随机坐标偏移来实现烟花的位置随机展示,在粒子播放的时候,会进行回归调用。

const xMin = -100.0;
const xMax = 150.0;
const yMin = -80.0;
const yMax = 150.0;
const zMin = -50.0;
const zMax = 50.0;

const colorOptions = [
{
minimumRed: 0.75,
green: 0.0,
minimumBlue: 0.8,
alpha: 1.0,
},
{
red: 0.0,
minimumGreen: 0.75,
minimumBlue: 0.8,
alpha: 1.0,
},
{
red: 0.0,
green: 0.0,
minimumBlue: 0.8,
alpha: 1.0,
},
{
minimumRed: 0.75,
minimumGreen: 0.75,
blue: 0.0,
alpha: 1.0,
},
];

for (let i = 0; i < numberOfFireworks; ++i) {
     const x = Cesium.Math.randomBetween(xMin, xMax);
     const y = Cesium.Math.randomBetween(yMin, yMax);
     const z = Cesium.Math.randomBetween(zMin, zMax);
     const offset = new Cesium.Cartesian3(x, y, z);
     const color = Cesium.Color.fromRandom(
          colorOptions[i % colorOptions.length]
     );

      const bursts = [];
      for (let j = 0; j < 5; ++j) {
            bursts.push(
              new Cesium.ParticleBurst({
                time: Cesium.Math.nextRandomNumber() * lifetime,
                minimum: burstSize,
                maximum: burstSize,
              })
            );
      }

    createFirework(offset, color, bursts);
}

下面给一个最终的效果图,一个在橘子洲头的动态烟花效果,真诚的祝福大家新年快乐,兔年大吉。

5、粒子系统加载

这里给的Cesium.js是编译之后的,所以对于debug不太友好,如果需要源码调试可以使用开发版本,可以观察到更深入的调用过程。对于理解粒子系统更加有帮助,调试起来吧。

总结

以上就是本文的所有内容,本文首先介绍了橘子洲头的一些相关知识,它与伟人的渊源,与烟花的关系。最主要的是介绍了基于Cesium的电子烟花的展示播放技术,重点介绍了在Cesium中如何进行集成,粒子系统的创建过程以及加载技术。最后祝所有的技术人都能一飞冲天,炫彩夺目。

有关兔年首文迎新春-Cesium橘子洲烟花礼赞的更多相关文章

  1. Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理) - 2

    快速导航(持续更新中…)Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理)Cesium源码解析二(metadataAvailability的含义)Cesium源码解析三(metadata元数据拓展中行列号的分块规则解析)Cesium源码解析四(Quantized-Mesh(.terrain)格式文件在CesiumJS和UE中加载情况的对比)目录1.前言2.本篇的由来3.terrain文件的加载3.1更新环境3.2更新和执行渲染命令3.3数据优化3.4结束当前帧4.总结1.前言  目前市场上三维比较火的实现方案主要有两种,b/s的方案主要是Cesium,c/s的方案主要是u

  2. javascript - 一张Cesium Map可以显示多少个点? - 2

    我试图在Cesiummap上放置数千个点,但遇到了Firefox崩溃的问题。我必须使用Firefox。该map似乎能够显示15,000个点(如图像)。但是,它也几乎无法使用。缩放和平移有巨大的延迟并最终崩溃。有谁知道极限应该是多少分?另外,有没有比我现在做的更好的方式来显示这些点?我真的希望是我而不是铯。我听说创建czml然后传入它比较慢,所以我有以下javascript测试:functiontest(){for(vari=0;i90){tempLat=0;tempLon=0;}addBillboard(scene,ellipsoid,tempLat,tempLon);}}//this

  3. javascript - Cesium DataSourceCollection层排序 - 2

    我有多个GeoJsonDataSource对象,我想将它们放在Cesium地球仪上。问题是,如果它们重叠,我会遇到一些z-fighting问题,我无法调整它们的顺序。有没有一种方法可以指定DataSourceCollection中DataSource对象的顺序?例如,我想使用以下代码将绿色多边形置于红色多边形之上:varviewer=newCesium.Viewer('cesiumContainer');varred=Cesium.GeoJsonDataSource.load('map1.geojson',{fill:newCesium.Color(1,0,0,1.0)});vargr

  4. Cesium 核心概念 核心接口 - 2

    Cesimum可以做什么Cesium是一个开源的3D地球可视化引擎,它可以在Web浏览器中以高性能和高质量呈现全球范围内的地球表面数据。Cesium可以用于以下领域:地理信息系统:Cesium可以呈现地球表面上的各种地理信息数据,包括卫星影像、数字高程模型、地形数据、矢量数据等。用户可以使用Cesium创建交互式的地图应用程序,从而更好地了解地球上的各种地理信息。智能城市:Cesium可以用于可视化城市规划、交通流量、气象预报、环境监测等数据。通过Cesium,用户可以更好地了解城市的运转情况,并对城市的规划、管理等方面进行决策。航空航天:Cesium可以呈现卫星轨道、星座分布、航空交通等数据

  5. javascript - 如何更改 Cesium map 中 EllipseOutlineGeometry 的宽度? - 2

    我正在遵循沙堡椭圆轮廓几何体。我想知道是否有办法让椭圆线的宽度变宽?有使用width属性使折线变宽的示例,但似乎没有办法制作ellipseOutlineGeometry对象。沙堡示例在末尾有一个lineWidth设置,但对此的更改似乎不会影响椭圆轮廓的宽度。沙箱代码://Createtheellipsegeometry.Toextrude,specifythe//heightofthegeometrywiththeextrudedHeightoption.//ThenumberOfVerticalLinesoptioncanbeusedtospecify//thenumberoflin

  6. javascript - 如何在浏览器中使用 npm 安装的 cesium - 2

    Cesium现在在npm上。在npminstallcesium之后-进入我的项目,所有代码进入node_modules.在铯中helloworld,它包括cesium通过类似的方式我的问题是,为了从html使用cesium,我需要执行哪些额外步骤? 最佳答案 有几种方法。如果正在提供node_modules文件夹本身,您可以从那里拉Cesium。在调试期间,使用未缩小的版本:@importurl(node_modules/cesium/Build/CesiumUnminified/Widgets/widgets.css);但对于生产

  7. javascript - 如何设置默认 View 位置 (Cesium 1.6) - 2

    我想为cesium应用程序设置默认View/主页位置。我不只是想飞到那个地点一次;我希望将位置设置为默认/家-以便它可以在应用程序的其他地方使用-例如在HomeButton小工具。我试过设置Camera.DEFAULT_VIEW_RECTANGLE(docshere)像这样:varextent=Cesium.Rectangle.fromDegrees(117.940573,-29.808406,118.313421,-29.468825);viewer.camera.DEFAULT_VIEW_RECTANGLE=extent;但是没用..为了完整起见,下面是我初始化应用程序的方式:va

  8. Cesium 中的离屏渲染 - 2

    Cesium中的离屏渲染本文参考了众多文章,均列在了最后。先感谢各位的分享精神,如觉有冒犯,请与我联系。部分内容来自个人理解,欢迎指正交流。为了达到更加真实的渲染效果或其他计算需求,很多时候需要利用被渲染物体在其他状态下(比如通过另一相机渲染)的中间渲染结果,处理到最终显示的渲染场景中。这种中间渲染结果,就保存在帧缓冲区对象(FrameBufferObject,FBO)中,包含颜色缓冲区和深度缓存区。由于其结果并不直接被显示出来,所以这种技术也被称为离屏渲染(Off-ScreenRendering)。在深入了解Cesium的离屏渲染前,需要先了解WebGL的渲染过程。WebGL渲染过程大家都知

  9. 【Python小游戏】2023兔年吉祥,祝大家辞旧迎新,前兔无量啦~兔年都在玩的这两款游戏,只有0.1%的人通关,你玩了吗?(内含福利源码) - 2

    前言HAPPYNEWYEAR——2023🐇年吉祥☀🌙🌙🌙🌙🌙🌙除夕辞旧迎新🌙🌙🌙🌙🌙🌙++新年快乐钱🐇无量++所有文章完整的素材+源码都在👇👇粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。当和家人围坐一席、觥筹交错举杯庆祝时,就轮到要说祝福语了~~这时的你,是不是经常大脑一片空白?只能从嘴里蹦出为数不多的几个字:吃好喝好!PS:兔年祝福——含“兔”的四字词语大展宏“兔”前“兔”似锦——“兔”步青云前“兔”无量“兔”然暴富“兔”来运转——扬眉“兔”气“兔”飞猛进奋发“兔”强钱“兔”无忧——全新“兔”破谈“兔”不凡“兔”出贡献好事成“兔”——金兔送福兔年大吉今天来给大家来两款Py

  10. SuperMap处理并发布矢量图层全流程+Cesium加载、移除图层以及点击图层查询对应属性信息 - 2

    前段时间想将某地的一些点线面矢量图层添加到Cesium视图中,到官网找了找示例发现有个“添加MVT”的示例,但是示例里面是将各矢量图层制作成了一幅地图并发布加载,而我的需求是在Cesium场景中通过图层管理模块将每个矢量图层单独加载或移除,具体实现见下文,如有不足欢迎评论区指正、交流。一、矢量数据处理及发布流程说明:本人使用的是64位SuperMapiDesktop11i和SuperMapiServer11.0.0版本软件。第一步:打开SuperMapiDesktop软件鼠标右击“数据源”→“新建文件型数据源”。第二步:鼠标右击新建的数据源点击“导入数据集”,选择需要导入的矢量图层点击“导入”

随机推荐