Three.js中加载和渲染3D Tiles
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的在线地图,另外还需要使用GLTFLoader和DRACOLoader以进行数据解析
<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/3d-tiles-renderer@0.3.30/+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/three@0.153.0/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);
}
加载的结果如下:

完整代码如下:
<!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/3d-tiles-renderer@0.3.30/+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/three@0.153.0/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>
上面加载的是日本东京的倾斜摄影数据,那在没有倾斜摄影数据的地方呢,比如中国的某些城市,答案是会加载类似于高程与遥感影像的合成数据,如下图:

此时只是把经纬度做以下修改:
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博客
Three.js中加载和渲染3D Tiles的更多相关文章
- java使用htmlunit工具抓取js中加载的数据
htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容.项目可以模拟浏览器运行,被誉为java浏览器的开源实现.这个没有界面的浏览器,运行速度 ...
- Three.js中加载外部fbx格式的模型素材
index.html部分: index.js部分: Scene.js部分:
- (转载)arcgis for js - 解决加载天地图和WMTS服务,WMTS服务不显示的问题,以及wmts服务密钥。
1 arcgis加载天地图和wmts服务 arcgis for js加载天地图的例子网上有很多,这里先不写了,后期有空再贴代码,这里主要分析下WMTS服务为什么不显示,怎么解决. 条件:这里的WMTS ...
- JS 动态加载脚本 执行回调_转
关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件里面的函数是不会成功的.本文讲解 ...
- JS 动态加载脚本 执行回调
JS 动态加载脚本 执行回调 关于在javascript里面加载其它的js文件的问题可能很多人都遇到过,但很多朋友可能并不知道怎么判断我们要加载的js文件是否加载完成,如果没有加载完成我们就调用文件 ...
- JS和CSS加载(渲染)机制不同
一.结论 CSS可以在页面加载完成后随时渲染.举个例子:通过js给某个元素加一个id或者css,只要这个id或者css有对应的样式,此元素的样式就会自动生效. JS不可以在页面加载完成后生效.最明显的 ...
- 浏览器加载和渲染html的顺序(html/css/js)
最近在学习前端的技术,把html.js.css的基础知识看了看.感觉越看越觉得前端并不比后端容易,技术含量还是相当大的.今天突然想弄明白浏览器到底是怎么加载和渲染html的?html中的DOM.js文 ...
- CSS样式表、JS脚本加载顺序与SpringMVC在URL路径中传参数与SpringMVC 拦截器
CSS样式表和JS脚本加载顺序 Css样式表文件要在<head>中先加载,这样网页显示时可以第一次就渲染出正确的布局和样式,网页就不会闪烁,或跳变 JS脚本尽可能放在<body> ...
- vue中加载three.js的gltf模型
vue中加载three.js的gltf模型 一.开始引入three.js相关插件.首先利用淘宝镜像,操作命令为: cnpm install three //npm install three也行 二. ...
- 在HTML中使用JavaScript(浏览器对js的加载机制分析)
前言: 向HTML页面中插入JavaScrip的主要方法,就是使用<script>标签.主要探讨<script>标签的在HTML页面的渲染机制.对应的业务场景:从js的加载机制 ...
随机推荐
- Linux shell的while循环
while循环 #!/bin/bash #其中":"表示while循环的条件永远为真的意思 while : do read -p "Enter a number [1-5 ...
- Laravel入坑指南(6)——Redis缓存
写在前面: Redis是常用nosql服务之一,在Redis官网上最新的稳定版本是6.0.6.这里不讨论Redis服务如何编译,如何使用.在Redis官网有很健全的文档. 这里要讨论的是无论在cent ...
- Ubuntu在无网络环境下,用离线源apt-get安装软件
步骤概要如下: 1.假设目标安装的是服务器A,需先准备一台正常环境,且操作系统版本与A一致的服务器B: 2.用apt-get在服务器B上下载需要安装的包,并用dpkg-scanpackages依赖打包 ...
- 使用virtualenv新建django项目
# 安装virtualenv pip install virtualenv # 创建虚拟环境 virtualenv venv # 进入虚拟环境 venv\Scripts\activate # 安装dj ...
- 多线程系列(七) -ThreadLocal 用法及内存泄露分析
一.简介 在 Java web 项目中,想必很多的同学对ThreadLocal这个类并不陌生,它最常用的应用场景就是用来做对象的跨层传递,避免多次传递,打破层次之间的约束. 比如下面这个HttpSer ...
- 【Android 逆向】【攻防世界】android2.0
这是一道纯算法还原题 1. apk安装到手机,提示输入flag,看来输入就是flag 2. jadx 打开apk查看 this.button.setOnClickListener(new View.O ...
- git commit 不生成 changeId 解决方案
1). 检查仓储 .git/hook 下面是否有 commit-msg 文件,如果没有可以到下面的地址下载,或者把其他同事的 commit-msg 文件拷贝到你的 .git/hook 重新commit ...
- MIG是如何向DDR中写入数据的
1.1 先来看看信号线的描述 我们以X16的器件为例,下面的截图来自 镁光的官方手册 https://media-www.micron.com/-/media/client/global/doc ...
- Centos下git pull免密码操作
在终端输入以下指令: git config --global credential.helper store然后再次执行pull操作,还是会提示一次输入帐号与密码.断开终端链接,重连,再次进行pull ...
- 【Azure 事件中心】Spring Cloud Stream Event Hubs Binder 发送Event Hub消息遇见 Spec. Rule 1.3 - onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially 异常
问题描述 开发Java Spring Cloud应用,需要发送消息到Azure Event Hub中.使用 Spring Cloud Stream Event Hubs Binder 依赖,应用执行一 ...