这是威尔逊Muktar关于整合Three.js与铯的客人帖子。Three.js是一个轻量级的跨浏览器JavaScript库,用于在浏览器中创建和显示动画3D计算机图形。将Cesium的行星级渲染和GIS功能与Three.js广泛而易用的通用3D API相结合,为新的WebGL体验开启了许多可能性。你可以在这里查看这个演示的实时版本和代码本身。 - 加里

3D JavaScript库现在已经完全成熟并且广为人知,使得开发人员可以避免在浏览器中使用3D的麻烦。开发人员可以轻松创建相机,对象,灯光,材质和图形,并选择渲染器,使用HTML 5的画布,WebGL或SVG绘制场景。

因为Cesium和Three.js都是用于3D可视化的,并且是从头开始用JavaScript构建的,所以它们有相似之处,可以将这些惊人的库集成在一起。我对这两个框架进行整合的方法比看起来简单:我将这两个框架分离到了不同的视图中,并参考了HTML Canvas元素,并将它们的控制器组合在同一个坐标系中。由于两者都是开源的,我可以分享这个演示,这将涵盖一些基础知识。

左:铯现场。中心:Three.js场景。右:组合的场景。

铯是一个为了创建数字地球而开发的三维图书馆,其渲染对于真实的地球来说是非常精确的。借助3D Tiles,开发人员可以将几乎所有内容都重新渲染到浏览器中的数字画布上。

指导铯的基本渲染原理与Three.js没有太大区别。Three.js是用于渲染3D对象的强大3D库。通过在两个场景中复制铯的球面坐标系和匹配的数字地球,很容易将两个单独的渲染引擎层整合到一个主场景中。我将给出一个关于其整合方法的简单说明,如下所示:

  • 初始化Cesium渲染器,
  • 初始化Three.js渲染器,
  • 初始化这两个库的3D对象,和
  • 循环渲染器。

主功能

该html需要三个容器和铯:

<body>
<div id="cesiumContainer"></div>
<div id="ThreeContainer"></div>
</body>
<script> main(); </script>

这是主要功能:

function main(){// boundaries in WGS84 to help with syncing the renderersvar minWGS84 = [115.23,39.55];var maxWGS84 = [116.23,41.55];var cesiumContainer = document.getElementById("cesiumContainer");var ThreeContainer = document.getElementById("ThreeContainer");var _3Dobjects = []; //Could be any Three.js object meshvar three = {renderer: null,camera: null,scene: null};var cesium = {viewer: null};initCesium(); // Initialize Cesium rendererinitThree(); // Initialize Three.js rendererinit3DObject(); // Initialize Three.js object mesh with Cesium Cartesian coordinate systemloop(); // Looping renderer
}

初始化铯渲染器

首先,我们可以通过添加自定义图像或默认提供的其他部分来自定义铯查看器。通过禁用Cesium的默认渲染循环,我们可以将其动画帧与Three.js同步。

function initCesium(){cesium.viewer = new Cesium.Viewer(cesiumContainer,{useDefaultRenderLoop: false,selectionIndicator : false,homeButton:false,sceneModePicker:false,navigationHelpButton:false,infoBox : false,navigationHelpButton:false,navigationInstructionsInitiallyVisible:false,animation : false,timeline : false,fullscreenButton : false,allowTextureFilterAnisotropic:false,contextOptions:{webgl: {alpha: false,antialias: true,preserveDrawingBuffer : true,failIfMajorPerformanceCaveat: false,depth:true,stencil:false,anialias:false},},targetFrameRate:60,resolutionScale:0.1,orderIndependentTranslucency : true,creditContainer : "hidecredit",imageryProvider : new Cesium.createTileMapServiceImageryProvider({url: 'Assets/imagery/NaturalEarthII/',maximumLevel : 5}),baseLayerPicker : false,geocoder : false,automaticallyTrackDataSourceClocks: false,dataSources: null,clock: null,terrainShadows: Cesium.ShadowMode.DISABLED});var center = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2,((minWGS84[1] + maxWGS84[1]) / 2)-1,200000);cesium.viewer.camera.flyTo({destination : center,orientation : {heading : Cesium.Math.toRadians(0),pitch : Cesium.Math.toRadians(-60),roll : Cesium.Math.toRadians(0)},duration: 3});
}

初始化Three.js渲染器

接下来我们简单地初始化Three.js强制阶段,包括场景,相机,渲染器和DOM元素。

function initThree(){var fov = 45;var width = window.innerWidth;var height = window.innerHeight;var aspect = width / height;var near = 1;var far = 10*1000*1000; // needs to be far to support Cesium's world-scale renderingthree.scene = new THREE.Scene();three.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);three.renderer = new THREE.WebGLRenderer({alpha: true});ThreeContainer.appendChild(three.renderer.domElement);
}

在两个库中初始化3D对象

使用实体对象可以简单地将Cesium对象添加到其查看器中; 例如,可以使用3D图形类来渲染在Three.js中创建的3D绘图对象网格,或者使用Three.js创建的任何其他3D对象。所有这些都保存在一个_3DObjects进一步处理,其中包含用于同步相机的额外信息。这里我们将渲染一个[Lathe geometry]和一个[dodecahedron]。请注意,Three.js呈现z-up,而Cesium呈现y-up。

function init3DObject(){//Cesium entityvar entity = {name : 'Polygon',polygon : {hierarchy : Cesium.Cartesian3.fromDegreesArray([minWGS84[0], minWGS84[1],maxWGS84[0], minWGS84[1],maxWGS84[0], maxWGS84[1],minWGS84[0], maxWGS84[1],]),material : Cesium.Color.RED.withAlpha(0.2)}};var Polygon = cesium.viewer.entities.add(entity);// Lathe geometryvar doubleSideMaterial = new THREE.MeshNormalMaterial({side: THREE.DoubleSide});var segments = 10;var points = [];for ( var i = 0; i < segments; i ++ ) {points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * segments + 5, ( i - 5 ) * 2 ) );}var geometry = new THREE.LatheGeometry( points );var latheMesh = new THREE.Mesh( geometry, doubleSideMaterial ) ;latheMesh.scale.set(1500,1500,1500); //scale object to be visible at planet scalelatheMesh.position.z += 15000.0; // translate "up" in Three.js space so the "bottom" of the mesh is the handlelatheMesh.rotation.x = Math.PI / 2; // rotate mesh for Cesium's Y-up systemvar latheMeshYup = new THREE.Group();latheMeshYup.add(latheMesh)three.scene.add(latheMeshYup); // don’t forget to add it to the Three.js scene manually//Assign Three.js object mesh to our object arrayvar _3DOB = new _3DObject();_3DOB.threeMesh = latheMeshYup;_3DOB.minWGS84 = minWGS84;_3DOB.maxWGS84 = maxWGS84;_3Dobjects.push(_3DOB);// dodecahedrongeometry = new THREE.DodecahedronGeometry();var dodecahedronMesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial()) ;dodecahedronMesh.scale.set(5000,5000,5000); //scale object to be visible at planet scaledodecahedronMesh.position.z += 15000.0; // translate "up" in Three.js space so the "bottom" of the mesh is the handledodecahedronMesh.rotation.x = Math.PI / 2; // rotate mesh for Cesium's Y-up systemvar dodecahedronMeshYup = new THREE.Group();dodecahedronMeshYup.add(dodecahedronMesh)three.scene.add(dodecahedronMeshYup); // don’t forget to add it to the Three.js scene manually//Assign Three.js object mesh to our object array_3DOB = new _3DObject();_3DOB.threeMesh = dodecahedronMeshYup;_3DOB.minWGS84 = minWGS84;_3DOB.maxWGS84 = maxWGS84;_3Dobjects.push(_3DOB);
}
function _3DObject(){this.graphMesh = null; //Three.js 3DObject.meshthis.minWGS84 = null; //location bounding boxthis.maxWGS84 = null;
}

循环渲染器

function loop(){requestAnimationFrame(loop);renderCesium();renderThreeObj();
}
function renderCesium(){cesium.viewer.render();
}

我们将克隆Three.js摄像头以匹配Cesium摄像头,因此不需要为Three.js分配鼠标控制器,但是由于Three.js DOM元素在Cesium之上,我们仍然需要将其删除。我们通过向pointer-events:noneThree.js渲染器添加CSS属性来删除它。现在一切都会根据铯的相机投影来渲染。

还有一个坐标转换要做,使对象在地球上正确显示。这包括将大地纬度/经度位置转换为笛卡儿XYZ,并使用WGS84区域从左下角到左上角的方向作为向上矢量,使物体指向地球中心。这也可以通过使用本地笛卡尔东北向或东北向下来计算。

function renderThreeObj(){// register Three.js scene with Cesiumthree.camera.fov = Cesium.Math.toDegrees(cesium.viewer.camera.frustum.fovy) // ThreeJS FOV is verticalthree.camera.updateProjectionMatrix();var cartToVec = function(cart){return new THREE.Vector3(cart.x, cart.y, cart.z);};// Configure Three.js meshes to stand against globe center position up directionfor(id in _3Dobjects){minWGS84 = _3Dobjects[id].minWGS84;maxWGS84 = _3Dobjects[id].maxWGS84;// convert lat/long center position to Cartesian3var center = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2);// get forward direction for orienting modelvar centerHigh = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2,1);// use direction from bottom left to top left as up-vectorvar bottomLeft  = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], minWGS84[1]));var topLeft = cartToVec(Cesium.Cartesian3.fromDegrees(minWGS84[0], maxWGS84[1]));var latDir  = new THREE.Vector3().subVectors(bottomLeft,topLeft ).normalize();// configure entity position and orientation_3Dobjects[id].graphMesh.position.copy(center);_3Dobjects[id].graphMesh.lookAt(centerHigh);_3Dobjects[id].graphMesh.up.copy(latDir);}// Clone Cesium Camera projection position so the// Three.js Object will appear to be at the same place as above the Cesium Globethree.camera.matrixAutoUpdate = false;var cvm = cesium.viewer.camera.viewMatrix;var civm = cesium.viewer.camera.inverseViewMatrix;three.camera.matrixWorld.set(civm[0], civm[4], civm[8 ], civm[12],civm[1], civm[5], civm[9 ], civm[13],civm[2], civm[6], civm[10], civm[14],civm[3], civm[7], civm[11], civm[15]);three.camera.matrixWorldInverse.set(cvm[0], cvm[4], cvm[8 ], cvm[12],cvm[1], cvm[5], cvm[9 ], cvm[13],cvm[2], cvm[6], cvm[10], cvm[14],cvm[3], cvm[7], cvm[11], cvm[15]);three.camera.lookAt(new THREE.Vector3(0,0,0));var width = ThreeContainer.clientWidth;var height = ThreeContainer.clientHeight;var aspect = width / height;three.camera.aspect = aspect;three.camera.updateProjectionMatrix();three.renderer.setSize(width, height);three.renderer.render(three.scene, three.camera);
}

cesium and three.js相关推荐

  1. cesium版本之间如何兼容_【JS】cesium与three.js 结合的栗子,结合了一下网友们的栗子,解决了three.js 高版本模型出不来的问题...

    废话不多说先上图 下面是源代码 html> content="width=device-width, initial-scale=1, maximum-scale=1, minimum ...

  2. 五、Vue引用Cesium调用Sandcastle-header.js文件中的方法

    <template><div><div id="cesiumContainer"><div id="toolbar"& ...

  3. Cesium粒子特效js封装(火焰、水枪、爆炸、喷雾、烟),包含demo图片

    基于1.9版本cesium封装了几个粒子功能 1.火焰 //火焰特效 export class FireEffect{constructor(viewer) {this.viewer=viewerth ...

  4. 配置Cesium编译环境

    1.安装node.js https://nodejs.org/en/ 2.配置node.js 在node.js安装目录下新建node_global.node_cache两个文件夹,并把node_glo ...

  5. cesium雷达图_20个简化开发任务的 JavaScript库

    所谓JavaScript库就是预先写好的可以简化基于JavaScript的应用程序开发的,尤其是Ajax和其它以web为中心的技术的 JavaScript代码集.JavaScript主要用于写内嵌于H ...

  6. Cesium是什么,简介

    Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以 ...

  7. 转载---Cesium简介

    转载---https://blog.csdn.net/mrib/article/details/78260971 Cesium是什么 Cesium 是一款面向三维地球和地图的,世界级的JavaScri ...

  8. 使用TLE(双行)根数计算出轨道数据以供Cesium使用

    使用TLE(双行)根数计算出轨道数据以供Cesium使用 资源: satellite.js:https://download.csdn.net/download/qq_41176306/1936095 ...

  9. 关于DEJA_VU3D - Cesium功能集专栏说明

    博主简介 博主90后专业GIS行业开发人员,一直从事GIS相关工作5年左右,主要涉及三维和地图可视化等内容.工作中难免要接触到相关开发框架,对Cesium,Three.js,openlayer,sky ...

最新文章

  1. 面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?
  2. ffmpeg 视频处理命令集合
  3. 阿里云查看mysql版本_查看mysql版本的四种方法及常用命令
  4. Android中的约束布局
  5. couchbase_Couchbase:使用Twitter和Java创建大型数据集
  6. 视频播放问题和提高性能方案
  7. linux vnc 改端口号,基于Linux中vnc配置端口号的修改方法
  8. python生成器yield原理_Python的迭代器和生成器 使用实例及yield的使用
  9. 分别使用U+、B+、UD制作WinPE启动盘
  10. JAVA模板模式,简历模板(例子)
  11. 推荐系统(原理介绍)
  12. oracle生成awr报告命令,oracle数据库生成awr报告
  13. 【黑马程序员】-c函数
  14. HTML与CSS实现淘宝静态页面(参考版)
  15. 【CVE】CVE-2015-5254:ActiveMQ 反序列化漏洞利用
  16. Python个人总结(基础+进阶)
  17. Python智力问答小游戏
  18. Android实战——简单网络视频播放器
  19. 如何训练一个通用人工智能
  20. 吸血鬼数字 java_找出吸血鬼数(Java)

热门文章

  1. 如何强制删除文件夹?这样操作就能搞定!
  2. SQL Server 索引
  3. zip 伪加密学习,压缩包十六进制数据含义分析
  4. 安装Xshell遇到 由于找不到MSVCR110.dll,无法继续执行代码。重新安装程序可能会解决此问题
  5. 原生js操作input文本框注册获取焦点、失去焦点事件,设置文本框默认值
  6. Python简单实现ATM自动存取款机
  7. pyqt5界面自适应
  8. Pygame经典游戏飞机大战,黑马程序员案例讲解
  9. MyCat的使用及其项目实战
  10. 科技创业公司最爱的9大工具箱