当前位置: 首页 > news >正文

从 DEM 到 3D 渲染:R 语言 rayshader 地形可视化全指南

一、为什么要用 rayshader?

当我们打开一张普通的地图时,看到的往往是平面的线条和色块。虽然我们可以通过等高线去想象山脉的起伏,或者通过蓝色的深浅去猜测湖泊的深浅,但这始终缺乏一种身临其境的震撼感。rayshader 的出现,就是为了打破二维平面与三维世界之间的那堵墙。 它不仅仅是一个绘图工具,更像是一位精通光影艺术的数字雕刻家。它能将那些枯燥的地理高程数据,转变为栩栩如生的微缩景观。

rayshader 最大的价值在于化繁为简,它依托于 R 语言,将极其复杂的 3D 渲染流程封装成了极简的指令。你不需要懂得如何计算光线的折射角度,也不需要手动去构建每一个山峰的模型,你只需要告诉它:“这里是数据,给我加上早晨 8 点的阳光”,它就能自动帮你完成剩下所有的任务。而且,rayshader 最迷人的地方在于它对真实感的追求。普通的 3D 地图往往看起来像是由塑料堆砌而成的玩具,缺乏质感。而 rayshader 引入了光线追踪与环境光遮蔽技术,它能精确模拟阳光是如何洒在山脊上的,云层的阴影是如何投射在深谷中的,甚至能模拟出大气层的雾气感和水面的波光粼粼。这种对光影的细腻处理,能让一张普通的地形图瞬间拥有艺术摄影般的质感。因此,其特别适合在GIS相关工作中应用。

二、数据读取与转换

首先打开RStudio,从开始菜单中或桌面快捷方式打开都可以:

图1 找到RStudio并打开

我们以示例数据集为例,将附件的数据集名字重命名为satellite_image.csv,然后将其粘贴到R的工作目录内。由于目前我们并不知道工作目录在哪,因此需要现在R studio中输入代码进行寻找:

getwd()

输入后,便能够得到返回结果,找到当前的工作目录:

图2 返回的工作目录

将获得的地址粘贴到此电脑的地址栏中,回车进入:

图3 粘贴到地址栏回车进入目录

将示例数据集改名并粘贴到这一目录:

图4 改名并粘贴

rayshader 并不直接分析 TIF 文件,它需要矩阵数据。因此,我们需要在 RStudio 中复制并粘贴运行以下代码:

# 0. 安装工具包 install.packages(c("rayshader", "terra")) # 1. 加载必要的工具包 library(rayshader) library(terra) # 2. 读取您的本地数据文件 # 这里我们使用 terra 包的 rast() 函数,就像把文件从硬盘里“拿”出来 # 注意:请确保 'satellite_image.tif' 文件在您的当前工作目录下,或者填写完整路径 tif_data <- rast("satellite_image.tif") # 3. 关键步骤:将地理文件转换为 rayshader 能识别的“矩阵” # rayshader 提供了一个贴心的函数 raster_to_matrix,专门负责这个翻译工作 elmat <- raster_to_matrix(tif_data) # 4. 检查一下是否成功 # 我们看看这个“表格”的大小 dim(elmat)

运行代码后,可以看到已经输出了结果:

图5 输出的检查结果

三、第一次 3D 渲染

数据准备好了,现在我们开始生成模型。rayshader制作 3D 地形就像是搭建积木,但我们不需要一块一块去搭,只需要两步简单的指令:先给它上色,再把它拉起。在 R 语言中,我们经常使用一个像管道一样的符号 %>%。可以把它想象成工厂里的传送带:数据从左边进去,经过加工后,传给下一个环节。这样写代码,就像在读句子一样自然。复制并粘贴运行以下代码:

# 这里的 elmat 是我们在上一节生成的矩阵数据 elmat %>% height_shade() %>% # 第一步:根据高度生成基础颜色(皮肤) plot_3d( # 第二步:根据矩阵数值构建 3D 模型(骨架) elmat, # 告诉它用哪个数据来决定山的高度 zscale = 30, # 【关键参数】海拔缩放比例(详见下文解读) fov = 0, # 摄像机视野,0 代表正交视图(像地图),70 代表透视(像人眼) theta = 45, # 摄像机的水平旋转角度(0-360度) phi = 45, # 摄像机的俯视角度(0-90度,90是垂直俯视,0是平视) windowsize = c(1000, 800), # 弹出的 3D 窗口大小 zoom = 0.7 # 初始缩放级别 )

代码中,height_shade() 代表根据高度给地图上色。低的地方涂上代表水的蓝色或平原的绿色,高的地方涂上代表山峰的白色或褐色。这相当于给模型穿了一层基础的皮肤。plot_3d() 则是 rayshader 的重要函数。它会根据我们之前的 elmat 高度矩阵,把平面的颜色“顶”起来,形成 3D 实体。

生成的结果如下图:

图6 生成的3D结果

按住鼠标左键拖动可以旋转模型,从东南西北各个角度观察山脉。按住鼠标右键拖动可以拉近或推远,像无人机一样俯冲进山谷,或者飞到高空概览全貌。按住鼠标中键拖动则是平移视图。虽然现在的地形看起来还比较简单,只有颜色过渡,但它已经是一个真正的三维实体了。接下来我们通过叠加图层和光影处理,让它变得像照片一样真实。

四、叠加图层:给地形穿衣服

如果说 plot_3d 是构建骨架,那么这一步就是给骨架穿上衣服。在专业的地图绘制中,我们很少只用一种颜色。通常,我们会把“光照质感”和“海拔颜色”混合在一起,甚至如果有卫星照片,也可以直接贴在模型表面。rayshader 强大的地方在于它允许我们像 Photoshop 一样,一层一层地叠加图片。

在上一节我们用了 height_shade(按高度上色)。现在我们使用更高级的函数:sphere_shade()。它会模拟光源照射在起伏地面上的效果,生成一张带有明暗阴影的“浮雕图”。这会让地形即使在平面状态下,看起来也有立体的质感。这个函数的搭配按照以下方式进行:

1.底图:使用 sphere_shade 生成的黑白浮雕,提供纹理细节。

2.覆盖层:使用 height_shade 生成的彩色高度图,提供直观的海拔信息。

3.混合:使用 add_overlay 将两者融合,类似给照片上色。

复制并粘贴运行以下代码:

install.packages("magick") # 1. 加载必要的库 library(rayshader) library(terra) library(magick) # 【关键】加载图像处理包,解决报错问题 # 2. 制作“内衣”:基于光照的黑白浮雕层 base_layer <- sphere_shade(elmat, texture = "bw", sunangle = 45) # 3. 制作“外套”:基于高度的彩色层 color_layer <- height_shade(elmat, texture = terrain.colors(256)) # 4. 穿衣并渲染 elmat %>% sphere_shade(texture = "bw", sunangle = 45) %>% add_overlay(color_layer, alphalayer = 0.6) %>% # 现在有了 magick,这一步就能成功了 plot_3d( elmat, zscale = 30, fov = 0, theta = 45, phi = 45, windowsize = c(1000, 800), zoom = 0.7 )

可以看到,结果已经被自动生成:

图7 生成的结果

现在,3D 地形图既有丰富的颜色,又有清晰的山体脉络。接下来,我们用阴影让它变得更加深邃。

五、添加阴影层

在现实世界中,光线不仅仅是直射的。在一个深邃的山谷底部,即使阳光没有直接照进去,也会因为周围山壁的遮挡而显得比较暗;而在开阔的山顶,光线则非常充足。这种“因为周围物体遮挡而产生的阴影”,在计算机图形学中叫做环境光遮蔽。

如果不加这一层,生成的山脉就像是用塑料做的,每个角落都很亮;加上这一层,山脉的皱褶感、深邃感会得以显现,就像给素描画加上了重重的阴影线条。

我们需要用到两个生成阴影的函数:

1.ray_shade():模拟太阳光产生的直接投影(比如山峰挡住了背后的光)。

2.ambient_shade():模拟环境光遮蔽(比如山谷缝隙里的暗部)。

接下来,我们将底色 + 太阳阴影 + 环境阴影叠在一起。复制并粘贴运行以下代码:

# 1. 计算太阳光阴影(Ray Shade) # 模拟太阳从西北方向(sunangle = 315)照射产生的硬阴影 # zscale = 30 必须与 plot_3d 中的一致,否则阴影位置会跑偏 ray_shadow <- ray_shade(elmat, sunangle = 315, zscale = 30) # 2. 计算环境光遮蔽(Ambient Shade) # 模拟山谷缝隙里的软阴影,这会让地形看起来更深邃 amb_shadow <- ambient_shade(elmat, zscale = 30) # 3. 混合所有图层并渲染 elmat %>% sphere_shade(texture = "bw", sunangle = 315) %>% # 底层:黑白光照 add_overlay(color_layer, alphalayer = 0.6) %>% # 中层:彩色高度(上一节做的) add_shadow(ray_shadow, max_darken = 0.5) %>% # 顶层1:叠加太阳阴影 add_shadow(amb_shadow, max_darken = 0.5) %>% # 顶层2:叠加环境阴影 plot_3d( elmat, zscale = 30, fov = 0, theta = 45, phi = 45, windowsize = c(1000, 800), zoom = 0.7

运行这段代码后,能够发现山谷的深处和山脊的背光面质感变得厚重了。这种充满电影质感的画面,就是光影魔法的魅力。接下来,我们进一步开启光线追踪,模拟真实的大气和光线反弹。

六、开启光线追踪

到目前为止,我们在 RGL 弹出窗口中看到的 3D 地形,只是一个实时预览版。为了保证拖动鼠标时画面流畅,电脑省略了很多复杂的光影计算。现在,我们要使用 render_highquality() 函数,启动光线追踪技术,计算每一束光线在山谷间的反射、折射和散射。

运行这段代码前,必须保持之前的预览 3D 窗口(RGL窗口)处于打开状态,并调整好最佳角度。运行代码后,R 会开始计算,可能需要几十秒,具体取决于电脑性能。复制并粘贴运行以下代码:

#这里的参数不再是控制模型,而是控制“摄影棚”的灯光和相机 render_highquality( lightdirection = 315, # 阳光照射的方向(西北方) lightaltitude = 45, # 阳光的高度(45度角,类似上午9点的太阳) lightintensity = 800, # 阳光的强度 samples = 200, # 【关键】采样数:数值越高,噪点越少,画质越细腻,但速度越慢 clear = TRUE # 渲染完成后,自动关闭那个 3D 预览窗口以释放内存 )

生成的结果如下所示:

图8 完成渲染的图出现在右下角

观察结果可以发现,阴影不再是完全黑暗,而是带有柔和的过渡(软阴影);原本生硬的棱角,现在被光线包裹得更加自然。这一步生成的图片,已经具备了作为壁纸或海报的潜质。但如果想让它看起来更像微距摄影作品,我们还可以加上最后一道滤镜——景深与虚化。

七、景深与虚化

在 rayshader 中,实现景深与虚化效果不需要昂贵的相机镜头,只需要调整一个参数:光圈。光圈越大,背景虚化越强烈。在 render_highquality() 函数中,我们只需要加入 aperture 参数:

1.aperture = 0:默认值。全图清晰,没有虚化(像手机拍风景)。

2.aperture = 10 到 30:适合地形图。会让远处和近处的山峰模糊,焦点集中在画面中心,产生强烈的微缩模型感。

复制并运行以下代码:

# --- 第一步:重新构建 3D 窗口--- # 这一步和之前一样,只是为了确保有一个东西可以被拍摄 elmat %>% sphere_shade(texture = "bw", sunangle = 315) %>% add_overlay(color_layer, alphalayer = 0.6) %>% add_shadow(ray_shadow, max_darken = 0.5) %>% add_shadow(amb_shadow, max_darken = 0.5) %>% plot_3d( elmat, zscale = 30, fov = 0, theta = 45, phi = 45, windowsize = c(1000, 800), zoom = 0.7 ) # --- 第二步:带景深的“微缩摄影” --- render_highquality( lightdirection = 315, lightaltitude = 45, lightintensity = 800, samples = 200, # 【新增核心参数】 aperture = 30, # 光圈大小。数值越大,虚化越强。建议尝试 10-50。 # 焦点位置:默认情况下,rayshader 会自动对焦在模型中心。 clear = TRUE # 渲染完关闭窗口 )

完成渲染后的效果如图所示:

图9加入景深与虚化后的效果

观察图片可以发现,画面中的山峰具有了清晰锐利的效果,画面边缘则呈现出了朦胧的模糊感。这种虚化效果能有效消除计算机生成的生硬感,让地形图看起来就像是专业插图。现在,我们已经完成了一幅作品,最后一步就是把它保存下来。

八、导出与分享

rayshader 提供了专门的函数,能以原始分辨率保存作品,确保每一个像素都清晰可见。如果刚刚运行完光线追踪渲染,图片显示在 Plots 面板里,则需要在 RStudio 右下角的 Plots 面板上方,点击右键,然后选择"Save Image as":

图10 右键并保存

随后,选择保存目录,点击 Save 即可完成保存:

图11 选择保存目录

另外,我们还可以生成一段航拍视角的旋转视频。复制并粘贴运行以下代码:

install.packages("av") library(av) library(rayshader) # 1. 确保 3D 窗口是打开的 # (如果之前关闭了,请重新运行一遍 plot_3d 的代码块) # 2. 生成旋转动画 # theta: 摄像机旋转的角度范围(0到360度) # phi: 摄像机的俯视角度(保持30度俯视) render_movie(filename = "mountain_flyover.mp4", type = "oscillate", frames = 360, # 总帧数,帧数越多视频越流畅 phi = 30, zoom = 0.6, title_text = "3D Terrain Flyover")

完成渲染后,视频的保存位置会显示在输出结果中:

图12 视频的保存位置

播放的效果如图所示:

图13 视频的播放效果

至此,我们完整走完了从一张 DEM 数据,到生成 3D 地形图的全过程,可以在实际研究或生产中进行应用了。

http://www.jsqmd.com/news/333353/

相关文章:

  • 上海知名的当幸烘焙品牌产品好不,费用怎么算? - 工业推荐榜
  • 2026年 南通短视频营销服务商推荐榜单:专业引流、代运营与广告投放策略深度解析 - 品牌企业推荐师(官方)
  • 2026年广西营销策划公司排名推荐:技术整合与合规标准维度,涵盖本地生活多元场景 - 品牌推荐
  • R语言网络分析与路径规划——线数据应用实战:规划散步路线
  • 2026年安阳锻压设备数控有限公司行业地位权威排名 - myqiye
  • 揭秘appium滑动屏幕技巧—实现用户仿真动作的多重方式
  • Python 地理数据处理——GeoTIFF 读取与分析实战
  • 酒店一次性用品性价比高的有哪些 杭州邦亿客在列吗 - 工业品网
  • <span class=“js_title_inner“>别对着报错发呆了!手把手教你还原 MySQL 死锁的“案发现场”</span>
  • 2026年广西营销策划公司权威测评报告:基于百家客户匿名反馈的口碑深度解析 - 品牌推荐
  • 中企出海如何筑牢安全合规防线,避开千万罚款业务畅行全球?——OceanBase 全链路合规解决方案实践
  • <span class=“js_title_inner“>为什么 Java 还要发生 STW (时间暂停)?</span>
  • yum配置本地光盘
  • <span class=“js_title_inner“>ThreadLocal 为什么要用弱引用?</span>
  • 鹤岗市英语雅思培训辅导机构推荐-2026权威出国雅思课程中心学校口碑排行榜 - 苏木2025
  • 2026年1月最新权威发布:广西营销策划公司综合实力TOP5全景解析 - 品牌推荐
  • 2026年海南营销策划公司推荐:基于多产业带横向对比评价,针对品牌出海与本土深耕痛点 - 品牌推荐
  • 2026年电子器件与智能控制国际学术会议(EDIC 2026)
  • 如何为不同行业选广西营销策划公司?2026年全面评测与推荐,直击预算与效果失衡痛点 - 品牌推荐
  • 2026 户外照明甄选指南:五大太阳能路灯厂家助力绿色基建,西安华冠领衔西北品质标杆 - 深度智识库
  • 矿山煤矿电力电缆生产厂家推荐:涵中低压、低压、中压、变频、聚乙烯绝缘、聚氯乙烯绝缘电缆厂家(2026年) - 品牌2025
  • promtail+loki+Grafana(适合轻量级-数据量不大)
  • Tailscale Serve and Funnel
  • Android 高级逆向工程师成长路线图
  • 鹤岗市英语雅思培训辅导机构推荐;2026权威出国雅思课程中心学校口碑排行榜 - 苏木2025
  • 2026年2月叉车读写器厂家推荐,读写器/叉车读写器厂家选择指南 - 品致汇
  • 2026年广东营销策划公司权威测评报告:基于百家客户匿名反馈的口碑深度解析 - 品牌推荐
  • 中国电缆一线品牌推荐:2026年中国电缆十大品牌推荐top榜盘点 - 品牌2025
  • 2026年PP/FRP/熙诚蜗壳永磁风机推荐:郑州熙诚环保科技,全系产品覆盖废气处理多场景 - 品牌推荐官
  • 抖音代运营选哪家?2026口碑厂家引领行业新风尚,企业号代运营/短视频获客/抖音推广,抖音代运营公司口碑推荐 - 品牌推荐师