首页 > 其他分享 >Three.js中加载和渲染3D Tiles

Three.js中加载和渲染3D Tiles

时间:2024-03-20 23:34:50浏览次数:17  
标签:Tiles const tilesRenderer THREE three Three new js

1. 引言

3D Tiles 是 3D GIS 中常见的三维数据格式,能否用Three.js来加载渲染呢?肯定是可以,Three.js只是一个WebGL框架,渲染数据肯定可以,但是加载、解析数据得手动解决

有没有一个第三方库解决这个问题呢?有,比如这个:NASA-AMMOS/3DTilesRendererJS: Renderer for 3D Tiles in Javascript using three.js (github.com)

这里就简要记录如何在Three.js中加载 3D Tiles

2. 加载3D Tiles

首先,搭建一个简单的三维场景

<!DOCTYPE html>
<html lang="en">
 
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		html,
		body,
		canvas {
			height: 100%;
			width: 100%;
			margin: 0;
		}
	</style>
	
</head>
 
<body>
	<canvas id="canvas"></canvas>
 
	<script type="importmap">
		{
			"imports": {
				"three": "https://unpkg.com/three/build/three.module.js",
				"three/addons/": "https://unpkg.com/three/examples/jsm/"
			}
		}
	</script>
	
	<script type="module">
		import * as THREE from 'three';
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
 
		const scene = new THREE.Scene();
 
		const canvas = document.querySelector('#canvas');
		const camera = new THREE.PerspectiveCamera(75,  canvas.clientWidth / canvas.clientHeight , 0.1, 1000);
		camera.position.z = 5;
 
		const renderer = new THREE.WebGLRenderer({
			canvas: document.querySelector('#canvas')
		});
		renderer.setSize(window.innerWidth, window.innerHeight, false)
		
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		const material = new THREE.MeshPhongMaterial({
			color: 0x00ff00
		});
		const cube = new THREE.Mesh(geometry, material);
		scene.add(cube);
 
		const light = new THREE.DirectionalLight(0xffffff, 1);
		light.position.set(0, 0, 5);
		scene.add(light);
 
		const controls = new OrbitControls( camera, renderer.domElement );
		
		function animate() {
			requestAnimationFrame(animate);
			cube.rotation.x += 0.01;
			cube.rotation.y += 0.01;
			renderer.render(scene, camera);
		}
		animate();
	</script>
</body>
 
</html>

然后是引入3DTilesRendererJS,这里引入的是GoogleTilesRenderer来加载Google的在线地图,另外还需要使用GLTFLoaderDRACOLoader以进行数据解析

<script type="importmap">
		{
			"imports": {
				"three": "https://unpkg.com/three/build/three.module.js",
				"three/addons/": "https://unpkg.com/three/examples/jsm/",
                "3DTilesRendererJS": "https://cdn.jsdelivr.net/npm/[email protected]/+esm"
			}
		}
</script>

<script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
    import { TilesRenderer, GoogleTilesRenderer } from '3DTilesRendererJS'
    import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
    // ...
</script>

下一步是加载谷歌在线3D Tiles并加入场景中

const tilesRenderer = new GoogleTilesRenderer( 'AIzaSyBQ7Wj99aTxRqET-22qYWGFcDCWgVDt89A' ); // 传入的是谷歌倾斜摄影的API key
tilesRenderer.setLatLonToYUp( 36.266494 * THREE.MathUtils.DEG2RAD, 120.460205 * THREE.MathUtils.DEG2RAD ); // Tokyo Tower

tilesRenderer.setCamera( camera );
tilesRenderer.setResolutionFromRenderer( camera, renderer );

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'https://unpkg.com/[email protected]/examples/jsm/libs/draco/gltf/' );

const loader = new GLTFLoader( tilesRenderer.manager );
loader.setDRACOLoader( dracoLoader );

tilesRenderer.manager.addHandler( /\.gltf$/, loader );

scene.add( tilesRenderer.group );

最后在每一帧中更新3D Tiles渲染器

function animate() {
    requestAnimationFrame(animate);
    tilesRenderer.update();
    // ...
    renderer.render(scene, camera);
}

加载的结果如下:

image-20240320163435241

完整代码如下:

<!DOCTYPE html>
<html lang="en">
 
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		html,
		body,
		canvas {
			height: 100%;
			width: 100%;
			margin: 0;
		}
	</style>
	
</head>
 
<body>
	<canvas id="canvas"></canvas>
 
	<script type="importmap">
		{
			"imports": {
				"three": "https://unpkg.com/three/build/three.module.js",
				"three/addons/": "https://unpkg.com/three/examples/jsm/"
			}
		}
	</script>
	
	<script type="module">
		import * as THREE from 'three';
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
		import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
        import { TilesRenderer, GoogleTilesRenderer } from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm'
        import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
 
		const scene = new THREE.Scene();
 
		const canvas = document.querySelector('#canvas');
		const camera = new THREE.PerspectiveCamera(75,  canvas.clientWidth / canvas.clientHeight , 0.1, 100000);
		camera.position.y = 500;
		camera.position.z = 500;
 
		const renderer = new THREE.WebGLRenderer({
			canvas: document.querySelector('#canvas')
		});
		renderer.setSize(window.innerWidth, window.innerHeight, false)
 
		const controls = new OrbitControls( camera, renderer.domElement );

        const tilesRenderer = new GoogleTilesRenderer( 'AIzaSyBQ7Wj99aTxRqET-22qYWGFcDCWgVDt89A' );
        tilesRenderer.setLatLonToYUp( 35.6586 * THREE.MathUtils.DEG2RAD, 139.7454 * THREE.MathUtils.DEG2RAD ); // Tokyo Tower

        tilesRenderer.setCamera( camera );
        tilesRenderer.setResolutionFromRenderer( camera, renderer );

        const dracoLoader = new DRACOLoader();
        dracoLoader.setDecoderPath( 'https://unpkg.com/[email protected]/examples/jsm/libs/draco/gltf/' );

        const loader = new GLTFLoader( tilesRenderer.manager );
        loader.setDRACOLoader( dracoLoader );

        tilesRenderer.manager.addHandler( /\.gltf$/, loader );

        scene.add( tilesRenderer.group );
		
		function animate() {
			requestAnimationFrame(animate);
            tilesRenderer.update();
			renderer.render(scene, camera);
		}
		animate();
	</script>
</body>
 
</html>

上面加载的是日本东京的倾斜摄影数据,那在没有倾斜摄影数据的地方呢,比如中国的某些城市,答案是会加载类似于高程与遥感影像的合成数据,如下图:

image-20240320163934943

此时只是把经纬度做以下修改:

tilesRenderer.setLatLonToYUp( 36.266494 * THREE.MathUtils.DEG2RAD, 120.460205 * THREE.MathUtils.DEG2RAD ); // 山东青岛

总的来说,有时可以在Three.js中加载这样的3D Tiles作为底图来使用,更多的使用方法可参考官方文档:NASA-AMMOS/3DTilesRendererJS: Renderer for 3D Tiles in Javascript using three.js (github.com)

3. 参考资料

[1] NASA-AMMOS/3DTilesRendererJS: Renderer for 3D Tiles in Javascript using three.js (github.com)

[2] 3D Tiles Renderer Options Example (nasa-ammos.github.io)

[3] threejs加载3dtiles(倾斜摄影)数据_threejs 3dtiles-CSDN博客

标签:Tiles,const,tilesRenderer,THREE,three,Three,new,js
From: https://www.cnblogs.com/jiujiubashiyi/p/18085596

相关文章

  • JWT(JSON WEB TOKEN)是玩具吗
    JWT当然不是玩具,理解其设计意图,和适用场景自然会发现存在的就是有价值的JWT:JSONWebToken起源和定义JWT(JSONWebToken)是由IETF(InternetEngineeringTaskForce)基于RFC7519规范定义的。它是一种用于在网络应用间传递信息的标准方法。JWT最初由无状态的分布式应用场......
  • CF765F,CF1793F,JSOI2009:区间最接近的两数
    link:https://codeforces.com/contest/765/problem/F据说是典中典问题(出现三次了)题意:给一个序列\(a_1,\dots,a_n\),有\(m\)次询问,每次询问给\(l,r(1\leql<r\leqn)\)问\(\min_{l\leqs<t\leqr}|a_s-a_t|\)\(1\leqn,m\leq10^5,a_i\leq10^9\).思路这个做法还是很妙,想......
  • 密码加密|jsencrypt|md5|加密解密的两种方式
    一、md5npminstallmd5二、JSEncrypt2.1介绍JSEncrypt属于RSA加密,RSA加密算法是一种非对称加密算法;2.2使用安装:npminstalljsencrypt--dev封装工具:utils/jsencrypt.jsimportJSEncryptfrom'jsencrypt/bin/jsencrypt.min'//密钥对生成http://web.cha......
  • js实现多个video,一个播放其他暂停
    window.onload=function(){varvideos=document.getElementsByTagName('video');//获取所有video//循环给所有video添加监听事件当前的video开始播时调用pauseAll将当前播放的video的索引传值过去for(vari=videos.length-1;i>=0;i--){(......
  • Three.js快速入门
    Three.js介绍创建目录并使用 npminit-y 初始化 package.json使用 npminstall--save-devparcel 安装 Web 应用打包工具 parcel这一步不是必须的,可以使用其他打包工具例如 webpack 等在目录中新建 src/index.html 和 src/script.js 两个文件<!DOCT......
  • 企业身份认证接口-身份证实名认证接口免费调用-Node.js接口调用教程
    现如今,无论是银行开户、办理社保、购买保险、在线教育、电商购物等等的应用场景,都需要进行身份证的实名认证。随着人工智能技术的不断开拓与创新,身份证实名认证已经逐步实现了智能化、在线化。也正因如此,企业对于身份证实名认证接口的需求也在不断增多。翔云身份证识别接口与身份......
  • 基于Java的校园电商物流云平台(Vue.js+SpringBoot)
    目录一、摘要1.1项目介绍1.2项目录屏二、功能模块2.1数据中心模块2.2商品数据模块2.3快递公司模块2.4物流订单模块三、系统设计3.1用例设计3.2数据库设计3.2.1商品表3.2.2快递公司表3.2.3物流订单表四、系统展示五、核心代码5.1查询商品5.2查询快递公......
  • Android视角看鸿蒙第七课(module.json5中的各字段含义之abilities)
    Android视角看鸿蒙第七课(module.json5中的各字段含义之abilities)导读今天一起来了解module.json5中的最后一个字段,也是最复杂的字段abilities官方文档Indicatesallabilitiesinthecurrentmodule.Thevalueisanarrayofobjects,eachofwhichrepresentsan......
  • 基于Java的医院门诊预约挂号系统(Vue.js+SpringBoot)
    目录一、摘要1.1项目介绍1.2项目录屏二、功能模块2.1功能性需求2.1.1数据中心模块2.1.2科室医生档案模块2.1.3预约挂号模块2.1.4医院时政模块2.2可行性分析2.2.1可靠性2.2.2易用性2.2.3维护性三、数据库设计3.1用户表3.2科室档案表3.3医生档案表3.4......
  • 基于Java的考研专业课程管理系统(Vue.js+SpringBoot)
    目录一、摘要1.1项目介绍1.2项目录屏二、功能模块2.1数据中心模块2.2考研高校模块2.3高校教师管理模块2.4考研专业模块2.5考研政策模块三、系统设计3.1用例设计3.2数据库设计3.2.1考研高校表3.2.2高校教师表3.2.3考研专业表3.2.4考研政策表四、系统展......