前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Three.js DEM建模与渲染

Three.js DEM建模与渲染

原创
作者头像
用户5687508
修改于 2021-07-20 06:37:45
修改于 2021-07-20 06:37:45
4.9K00
代码可运行
举报
运行总次数:0
代码可运行

在这个教程中,我们将学习如何使用three.js渲染土耳其最高的Ağrı山脉的数字高程模型(DEM)数据,使用的工具包括Three.js、geotiff、webpack和QGIS。

我们将要使用的数据是由USGS (美国地质调查局)免费提供的。使用USGS Earth Explorer我下载了Ağrı山脉的DEM(数字高程模型)和卫星图像,这是一个休眠的火山,也是土耳其境内最高的山。

我使用USGS应用程序下载了一些卫星影像,然后尝试着找出云层覆盖率小于10%的图像:

Landsat🛰️ - 用卫星影像做纹理

如果你不熟悉遥感和图像处理,你可能没有听说过Landsat。Landsat是由美国地质调查局控制的卫星,为研究人员提供约30平方米的分辨率的科学卫星图像已经很多年了。图像的一个像素覆盖30平方米的地面区域,卫星的摄像头与地球垂直。现在,有些卫星的分辨率可以做到小于一米,但一般来说,它们的数据不能免费获得。所以,Landsat对我们来说已经足够了,我们将使用Landsat卫星影像作为我们的3D模型的纹理。

下载Landsat卫星图像可以点这里。图像的云层覆盖范围应小于 10%,并且应将其添加到标准中。很难找到一个好的,因为山是如此之高,大部分情况下图像中都有很多云。在找到合适的图像后,我意识到Landsat覆盖了一个巨大的区域,需要裁剪感兴趣的区域作为3D模型的纹理。但更重要的是,我们需要一个数字高程模型来将山脉可视化。

SRTM🗻 - 栅格化DEM数据

SRTM是Shuttle Radar Topography Mission的缩写,中文含义是航天飞机雷达地形任务。SRTM由美国宇航局运营,提供栅格化的数字高程模型。SRTM 的 30平米 分辨率的DEM数据,意味着一个像素覆盖约30平米的面积,并且将该地区的平均高程作为像素值。这些数据对于使用three.js生成我们的山地模型非常有价值。

数据预处理

我们使用 QGIS栅格工具剪切、制作DEM和相关卫星图像的掩膜,并将它们复制到工作目录:

看起来像Mouth Doom,这是在QGIS中使用默认调色板显示高程模型的效果。考虑到性能问题,我裁剪了两个不同尺寸的图像,你可以在代码仓库中找到。在下面的示例中我们将使用其中较小的那个以便快速查看运行结果。

Three.js

Three.js是一个优秀的JS库,使WebGL更易于使用WebGL。在three.js世界中,我们需要一些基本的设置,其中的4个基本组件是:

  1. 场景
  2. 渲染器
  3. 相机
  4. 对象(包含材质)

添加场景灯光

我们将从添加场景开始,然后设置渲染器、摄像头、控件和光线。添加光线至关重要,否则你在场景中看不到任何东西。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 setupLight() {
    this.light = new THREE.DirectionalLight(0xffffff);
    this.light.position.set(500, 1000, 250);
    this.scene.add(this.light);
  }

用DEM数据生成山的模型

我们要渲染的几何形状不是使用Blender、Maya等软件建模的,相反,我们将使用DEM数据直接用js生成一个3D模型,借助于"geotiff"库:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import * as GeoTIFF from "geotiff";

  setupTerrainModel() {
    const readGeoTif = async () => {

     ... 
     
    };

    readGeoTif();
  }

首先读取图像文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const rawTiff = await GeoTIFF.fromUrl(terrain);
const tifImage = await rawTiff.getImage();
const image = {
  width: tifImage.getWidth(),
  height: tifImage.getHeight()
};

// Our initial plane geometry
const geometry = new THREE.PlaneGeometry(
  image.width,
  image.height,
  image.width - 1,
  image.height - 1
);

在setupTerrainModel函数实现中,将剪裁的图像添加到项目后,我们使用geotiff库来读取DEM文件,并添加一个新的与DEM图像相同大小的PlaneGeometry对象。好了,让我们来生成这个大家伙:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Read image pixel values that each pixel corresponding a height
const data = await tifImage.readRasters({ interleave: true });

// Fill z values of the geometry
console.time("parseGeom");
geometry.vertices.forEach((geom, index) => {
  geom.z = (data[index] / 20) * -1;
});
console.timeEnd("parseGeom");

接下来我们读取每个像素的值 - 对应于高程值。我只是试探地将这个值除以20,使其看起来不错,并乘以-1,否则模型将颠倒过来 —这是因为three.js的z坐标方向 —我稍后会解释。使用console.time来跟踪代码性能。

现在我们的模型就可以显示出来了,但没有卫星图像,它只是一个3D白模:

纹理拟合

生成模型后,我们将使用 RGB 卫星图像,该图像也是之前用 QGIS 剪接的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import * as mountainImage from "../textures/agri-small-autumn.jpg";

// ... other stuff

const texture = new THREE.TextureLoader().load(mountainImage);
const material = new THREE.MeshLambertMaterial({
  wireframe: false,
  side: THREE.DoubleSide,
  map: texture
});

我们正在加载卫星图像,并保存在material变量中,以便后续在Three.js的 MESH对象上使用。不要忘记旋转对象,因为three.js采用右手坐标系,这意味着,默认情况下,Z轴不是朝上而是指向你。关于这一点的详细解释可以查看这里

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const mountain = new THREE.Mesh(geometry, material);
mountain.position.y = -100;
mountain.rotation.x = Math.PI / 2;

this.scene.add(mountain);

你可以在开始时使用camera.up.set(0,0,1)旋转 x 轴或旋转相机,然后在上面放置山的模型,沿y 轴向下移动一点点,稍微调整下,就可以了。

源代码下载:


原文链接:用Three.js可视化数字高程模型 — BimAnt

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
在Gazebo中使用DEM構建起伏地形環境
1. https://bitbucket.org/osrf/gazebo_tutorials/raw/default/dem/files/
zhangrelay
2022/11/30
1.5K0
在Gazebo中使用DEM構建起伏地形環境
谷歌地球引擎GEE下载DEM数据
  本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,批量下载指定时间与空间范围内的数字高程模型(DEM)数据的方法。本文是谷歌地球引擎(Google Earth Engine,GEE)系列教学文章的第23篇。
疯狂学习GIS
2024/11/28
4170
谷歌地球引擎GEE下载DEM数据
Google Earth Engine(GEE)——R 语言图像概览
栅格数据在 Earth Engine中表示为Image对象。图像由一个或多个波段组成,每个波段都有自己的名称、数据类型、比例、遮罩和投影。每个图像都将元数据存储为一组属性。
此星光明
2024/02/02
3100
Google Earth Engine(GEE)——R 语言图像概览
Three.js贴图技巧:优化性能与效果
在当今数字化的时代,WebGL 技术为开发者们打开了一扇通往交互式 3D 图形世界的大门,而 Three.js 作为JavaScript库中的佼佼者,凭借其简单易用的 API 和丰富的功能,在创建3D场景和交互应用方面得到了广泛应用。在Three.js构建的虚拟世界中,贴图扮演着至关重要的角色。从赋予模型逼真的材质质感,到增强场景的视觉吸引力,贴图的质量直接影响着用户的体验。然而,随着场景复杂度的增加和贴图数量的增长,如何在保证贴图效果的同时优化性能,成为了开发者们必须面对的重要课题。本文将深入探讨Three.js贴图的相关知识,分享一系列优化性能与效果的实用技巧,并通过丰富的代码示例进行详细说明,帮助读者更好地理解和应用这些技巧,从而提升Three.js项目的品质。
Front_Yue
2025/03/11
3900
Three.js贴图技巧:优化性能与效果
用Three.js建模
在Three.js中,一个可见的物体是由几何体和材料构成的。在这个教程中,我们将学习如何从头开始创建新的网格几何体,研究Three.js为处理几何对象和材质所提供的相关支持。
用户5687508
2021/07/17
7.8K0
我是如何用 Three.js 在三维世界建房子的(详细教程)
这两天用 Three.js 画了一个 3D 的房子,放了一个床进去,可以用鼠标和键盘控制移动,有种 3D 游戏的即视感。
神说要有光zxg
2021/12/10
5.4K0
我是如何用 Three.js 在三维世界建房子的(详细教程)
three.js中的重要基础概念
Three.js 是一个功能强大的 JavaScript 库,用于创建和展示基于 WebGL 的三维图形。在学习使用Three.js来构建3D世界之前,有一些基本概念是需要牢记的,否则,在你绘制3D世界时,思绪会是杂乱无章的:
fastmock
2025/04/26
1310
Landsat Collection 2 数据集详细介绍(T1/T2产品差异)
Landsat Collection 2 是对 Landsat 档案的第二次主要再处理工作,它带来了多项数据产品改进,这些改进应用了数据处理、算法开发以及数据访问和分发功能方面的进步。
此星光明
2024/02/02
8080
Landsat Collection 2 数据集详细介绍(T1/T2产品差异)
Google Earth Engine——WWF/HydroSHEDS/03VFDEM该数据集的分辨率为3弧秒。3角秒的数据集是虚空填充DEM、水文条件DEM和排水(流)方向
HydroSHEDS is a mapping product that provides hydrographic information for regional and global-scale applications in a consistent format. It offers a suite of geo-referenced datasets (vector and raster) at various scales, including river networks, watershed boundaries, drainage directions, and flow accumulations. HydroSHEDS is based on elevation data obtained in 2000 by NASA's Shuttle Radar Topography Mission (SRTM).
此星光明
2024/02/02
1930
Google Earth Engine——WWF/HydroSHEDS/03VFDEM该数据集的分辨率为3弧秒。3角秒的数据集是虚空填充DEM、水文条件DEM和排水(流)方向
『Three.js』场景 Scene
在阅读本文前,我希望你对 Three.js 有一个初步的理解。如果你不清楚 Three.js 是什么,我推荐你先阅读 『Three.js』起飞!
德育处主任
2022/08/30
5.8K0
『Three.js』场景 Scene
用three.js渲染上海外滩模型
天空的实现有多种方式,最常见的是一个包围全部的天空球,通常是UV球,也叫经纬球,其UV很方便映射到一张天空图片,比如:
Jean
2021/07/16
3.6K0
.glb格式的模型怎么在three.js中展示
3D软件中导出的格式一般有.obj 和.glb ,下面是blender 2.8.2 生成模型并在three.js中展示的流程
tianyawhl
2020/11/24
16.1K2
.glb格式的模型怎么在three.js中展示
教你如何用Three.js创造一个三维太阳系
笔者认为Three.js是一个伟大的框架,为什么这样说,因为它可以让我们轻易创造三维世界,甚至好像笔者写这遍教程,可以创造一个太阳系,在这个三维世界里你就是创世主。哈哈!好像说得有点夸!!
lizhenwen
2021/07/18
2.8K2
教你如何用Three.js创造一个三维太阳系
用 Three.js 画一个哆啦A梦的时光机
在 three.js 里以向右的方向为 x 轴,向上的方向为 y 轴,向前的方向为 z 轴:
神说要有光zxg
2023/08/28
6110
用 Three.js 画一个哆啦A梦的时光机
用Three.js构建三维世界的房子
最近在学习Three.js,无奈不知道从哪里下手,查阅大部分资料都是先介绍渲染器(Renderer)、场景(Scene)、照相机(Camera),其实这些概念确实需要了解,如果不给你立体模型,你始终是无法理解的。网上看了一个大佬(神说要有光)的教程,感觉算是一只脚已经入了门,接下来我们通过这篇文章,从造物主的视角开始创建一个房子。我们先看下最终效果。
青年码农
2022/12/13
2K0
用Three.js构建三维世界的房子
前端新玩具——webGL简介
在最初的六天,我创造了天与地 webGL是基于OpenGL的Web3D图形规范,是一套JavaScript的API。简单来说,可以把它看成是3D版的canvas。恩,你会这样引入canvas对吧:
IMWeb前端团队
2017/12/29
3.3K0
前端新玩具——webGL简介
Three.js可视化企业实战WEBGL网-2024入门指南
Three.js 是一个功能强大的 JavaScript 库,用于在 Web 浏览器中创建和显示动画 3D 图形。它的丰富 API 和模块化设计使得开发者可以轻松构建复杂的 3D 场景和动画效果。本文将详细介绍 Three.js 中的一些重要组件和模块,包括场景、相机、几何体、材质、光源、渲染器和控制器等。
用户11130883
2024/05/31
3730
Three.js深入浅出:2-创建三维场景和物体
以上demo总结来说,使用了 Three.js 库创建了一个简单的绿色立方体模型,并实现了旋转动画效果。 总结一下它的步骤:
用户6297767
2023/11/21
9610
Three.js深入浅出:2-创建三维场景和物体
Three.js实战—中国地图
这里涉及到一个知识点,墨卡托投影转换。墨卡托投影转换可以把我们经纬度坐标转换成我们对应平面的2d坐标。具体原理
阶钟
2024/12/03
1.9K0
Three.js实战—中国地图
利用 Three.js 实现汽车模型的自动躲避功能
在现代计算机图形学中,Three.js作为一个强大的WebGL库,为开发者提供了创建复杂3D场景的能力。本文将详细介绍如何利用Three.js加载GLTF模型,并实现一个简单的汽车自动躲避功能。我们将逐步解析代码实现的每一个环节,并深入探讨其中的关键概念与技术。
不惑
2025/01/06
4992
利用 Three.js 实现汽车模型的自动躲避功能
相关推荐
在Gazebo中使用DEM構建起伏地形環境
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验