cesium and three.js【转】
https://blog.csdn.net/zhishiqu/article/details/79077883
这是威尔逊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 renderers
- var 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 mesh
- var three = {
- renderer: null,
- camera: null,
- scene: null
- };
- var cesium = {
- viewer: null
- };
- initCesium(); // Initialize Cesium renderer
- initThree(); // Initialize Three.js renderer
- init3DObject(); // Initialize Three.js object mesh with Cesium Cartesian coordinate system
- loop(); // 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 rendering
- three.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 entity
- var 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 geometry
- var 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 scale
- latheMesh.position.z += 15000.0; // translate "up" in Three.js space so the "bottom" of the mesh is the handle
- latheMesh.rotation.x = Math.PI / 2; // rotate mesh for Cesium's Y-up system
- var 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 array
- var _3DOB = new _3DObject();
- _3DOB.threeMesh = latheMeshYup;
- _3DOB.minWGS84 = minWGS84;
- _3DOB.maxWGS84 = maxWGS84;
- _3Dobjects.push(_3DOB);
- // dodecahedron
- geometry = 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 scale
- dodecahedronMesh.position.z += 15000.0; // translate "up" in Three.js space so the "bottom" of the mesh is the handle
- dodecahedronMesh.rotation.x = Math.PI / 2; // rotate mesh for Cesium's Y-up system
- var 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.mesh
- this.minWGS84 = null; //location bounding box
- this.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 Cesium
- three.camera.fov = Cesium.Math.toDegrees(cesium.viewer.camera.frustum.fovy) // ThreeJS FOV is vertical
- three.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 direction
- for(id in _3Dobjects){
- minWGS84 = _3Dobjects[id].minWGS84;
- maxWGS84 = _3Dobjects[id].maxWGS84;
- // convert lat/long center position to Cartesian3
- var center = Cesium.Cartesian3.fromDegrees((minWGS84[0] + maxWGS84[0]) / 2, (minWGS84[1] + maxWGS84[1]) / 2);
- // get forward direction for orienting model
- var 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-vector
- var 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 Globe
- three.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【转】的更多相关文章
- Cesium应用篇:1快速搭建
范例中所有范例可以在Github中搜索:ExamplesforCesium Cesium ['siːzɪəm]是一款开源的JavaScript开源库,开发者通过Cesium,实现无插件的创建三维球和二 ...
- [转][cesium]1.添加本地服务器
转自:http://www.cnblogs.com/fuckgiser/p/5633748.html 此系列cesium总教程: https://www.cnblogs.com/fuckgiser/ ...
- Cesium应用篇:1快速搭建 【转】
范例中所有范例可以在Github中搜索:ExamplesforCesium Cesium ['siːzɪəm]是一款开源的JavaScript开源库,开发者通过Cesium,实现无插件的创建三维球和二 ...
- 转:Cesium 和 Webpack
原文地址:https://www.jianshu.com/p/85917bcc023f 注意:webpack 和 webpack-cli 的安装参考 https://www.cnblogs.com/m ...
- Cesium资料大全
前言 Cesium是一个用于显示三维地球和地图的开源js库.它可以用来显示海量三维模型数据.影像数据.地形高程数据.矢量数据等等.三维模型格式支持gltf.三维瓦片模型格式支持3d tiles.矢量数 ...
- Cesium官方教程13--Cesium和Webpack
原文地址:https://cesiumjs.org/tutorials/cesium-and-webpack/ Cesium 和 Webpack Webpack是非常强大非常流行的JavaScript ...
- Cesium参考资源
Reference resources cesium官网 cesium 下载 cesium官方文档 APIs cesium-workshop github cesium 官方示例 cesium git ...
- Cesium中级教程10 - CesiumJS and webpack
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ webpack是打包JavaScript模块流行且强大的工具.它 ...
- 20个简化开发任务的 JavaScript库
所谓JavaScript库就是预先写好的可以简化基于JavaScript的应用程序开发的,尤其是Ajax和其它以web为中心的技术的 JavaScript代码集.JavaScript主要用于写内嵌于H ...
随机推荐
- Xamarin iOS教程之页面控件
Xamarin iOS教程之页面控件 Xamarin iOS 页面控件 在iPhone手机的主界面中,经常会看到一排小白点,那就是页面控件,如图2.44所示.它是由小白点和滚动视图组成,可以用来控制翻 ...
- 常见的网络攻击(XSS,SQL注入,CSRF)
一.XSS 二.SQL注入 三.CSRF
- 【HDU 5382】 GCD?LCM! (数论、积性函数)
GCD?LCM! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- Wannafly 22A
题解 另g = gcd(a1,a2,a3....) 那么k * g % m的方案书就是答案 这个式子子显然是有循环节的 x * g = 0 mod m ,x * g + y * m = 0 exgcd ...
- 【LCA+MST】BZOJ3732-Network
[题目大意] 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N.图中有M条边 (1<=M<=30,000) ,第j条边的长度:d_j (1<=d_j ...
- 关于dubbo服务的xml配置文件报错的问题
在配置dubbo服务的过程中,经常会遇到虽然程序能够跑起来,但是配置文件一堆红叉,虽然不影响功能,但是确实很让人恶心. 报错信息如下: Multiple annotations found at th ...
- 【stanford C++】容器III——Vector类
主要介绍如下5个容器类——Vector, Stack,Queue,Map和Set,各个都表示一重要的抽象数据类型.另外,各个类都是一些简单类型的值的集合,所以称它们为容器类. 暂且我们先不需要知道它们 ...
- Revit API创建一个拷贝房间内对象布局命令
本课程演示创建一个拷贝房间内对象布局命令,完整演示步骤和代码.这个命令把选中房间内的对象复制到其它选中的一个或多个房间中,而且保持与源房间一致的相对位置.通过本讲座使听众知道创建一个二次开发程序很简单 ...
- .NET轻量级ORM组件Dapper葵花宝典
一.摘要 为什么取名叫<葵花宝典>? 从行走江湖的世界角度来讲您可以理解为一本"武功秘籍",站在我们IT编程的世界角度应该叫"开发宝典". 如果您在 ...
- 该对象尚未初始化。请确保在所有其他初始化代码后面的应用程序启动代码中调用 HttpConfiguration.EnsureInitialized()。
WebAPI使用属性路由,配置config.MapHttpAttributeRoutes();后出现错误: System.InvalidOperationException: 该对象尚未初始化.请确保 ...