简介:BlenderGIS是一个在Blender与地理数据之间搭建桥梁的插件,面向3D建模师、GIS开发者以及需要将地形、卫星影像或OSM数据引入三维场景的用户。压缩包内共131个文件,以78个Python脚本为插件核心代码,另含32个SVG界面图标、13个PNG预览图、2个Markdown说明文档以及许可证、配置等文件,整体仅402KB,结构紧凑。已有6855人学习,常用于快速实现地理参考相机、激光雷达点云、地形高程与OpenStreetMap数据的可视化。借助附带的README和示例资源,可了解各模块的调用方式,并在此基础上扩展自定义导入流程,适合作为地理空间数据可视化入门或Blender插件开发的参考。1. 3D-BlenderGIS.zip 是什么:一条从二维地图到三维地形的直通车道做可视化、游戏关卡、数字孪生或者航拍路线规划时,最头疼的不是建模本身,而是把真实世界的地理数据搬进三维软件。手动把高程点描成网格、再把卫星图一张张贴上去,等于用石器时代的工具干农业时代的活儿。这个 zip 包里的东西,就是用来解决这个问题的一整套桥梁方案:它让 Blender 直接读取常见地理数据格式(GeoTIFF、Shapefile、栅格影像),把经纬度、海拔、建筑轮廓转成可编辑的网格和材质,几秒钟内生成一个带有真实地形起伏和影像纹理的三维地表。这个方案最打动我的点是它的定位:不是把 Blender 变成一个 GIS 软件,而是把 GIS 数据翻译成 Blender 能听懂的语言。你做倾斜摄影、白模、地形漫游、流域分析可视化,它都能作为数据入口;它不会替你完成分析,但能把分析结果以三维形式呈现出来。适合的人群很明确——用 Blender 做地信相关可视化但又不想学整套 QGIS 建模流程的开发者,以及需要快速出地形原型给客户确认方向的从业者。我最早用它是为了做一个某区域的山体滑坡模拟 Demo,当时手上只有一份 GeoTIFF 高程和一个航拍影像。从安装到生成带纹理的地形,只花了一个小时,而以前手动建网格至少需要一整天。接下来的内容会把这套流程完整走一遍,包括安装、操作、参数设置和最容易翻车的地方。2. 安装与环境准备:从 zip 包到 Blender 里出现一个能用面板2.1 安装流程:不是把 zip 塞进 Blender 就完事拿到这个 zip 之后,最常见的翻车是把整个压缩包直接拖进 Blender。Blender 的插件安装机制要求的是压缩包内包含符合规范的插件目录结构,也就是addons/某个名字/__init__.py这种布局。正确的做法是在 Blender 的菜单栏里走:编辑 → 偏好设置 → 插件 → 右上角下拉箭头 → 从磁盘安装,然后在弹出的文件窗口里直接选中这个 zip 文件本身,不用提前解压。# 如果你喜欢用脚本安装,也可以在 Blender 的 Python 控制台里执行 import addon_utils import bpy # 启用插件,addon_name 需要替换成解压后实际目录名 addon_utils.enable("blender_gis", default_set=True, persistent=True) bpy.ops.wm.save_userpref()这段代码第一行导入的是 Blender 内部的插件管理工具,不需要用 pip 安装任何东西;第二行启用插件并把它写入用户偏好,这样下次启动 Blender 就不需要重新启用。运行完到偏好设置里确认一下该插件名称前出现了勾选框,如果没出现,多半是 zip 结构不对,先把 zip 解压到本地,看是不是有一层嵌套目录。常见情况是解压出来是某文件夹/某个名字/__init__.py,而 Blender 要求的是直接面对某个名字/__init__.py这级目录,此时把内层目录再压成 zip 即可。2.2 运行环境与前置依赖:你不需要 QGIS,但要有 GPU 哪怕很弱BlenderGIS 核心功能依赖的只有 Blender 本身,以及系统里能读取 GeoTIFF 的基础库。Blender 自带完整的 TIFF 支持,所以这一步通常不需要额外配置。如果你在 Windows 上使用,建议保持 Python 环境是 Blender 内置版本,不要单独安装其他 Python,避免库冲突。在项目实践中,某开发者在 Linux 服务器上跑过同样的流程,需要额外安装的是系统级的libgdal用于处理投影转换,这个在大多数发行版仓库里都能直接装。# Linux 下可能需要的基础库,按发行版差异包名略有不同 sudo apt install libgdal-dev gdal-bin这句命令带来的不止是 GDAL 命令行工具,更重要的是让 Blender 内部调用的底层库能识别各类投影坐标信息。如果你只是在本机做地形可视化,不涉及跨投影转换,这步可以跳过;但如果你要导入的数据投影不是常规的经纬度,比如 UTM 分区投影,依赖不装,导入后地形会错位得离谱。还有一个容易被忽略的检查点:Blender 版本必须大于 2.8,插件在早期版本上的行为完全不同。2.3 面板长什么样:激活后你的 3D 视口多了什么正确安装后,按 N 键展开右侧工具栏,会看到一个新标签页。这个标签页里通常有地形导入、影像导入、对象导出、坐标设置几个组。初次使用建议先别急着导入数据,打开几何节点编辑器确认没有报错提示,然后在场景属性里检查单位设置。Blender 默认单位是米,但地理坐标里经常用到度、千米,如果不统一单位,导入的网格会大得吓人或者小得看不见。接下来我会用一个具体工作流说明每个参数在实际中该设成什么,但在此之前,记住一个心法:这个插件的核心思维是把真实世界坐标换算成 Blender 的世界坐标,所有参数设置都围绕坐标变换进行。你不需要理解底层矩阵计算,但必须知道它有一个坐标缩放参数,而且这个参数极大影响场景比例,后面会有单独一章讲述如何调整。3. 第一次跑通完整流程:用高程 GeoTIFF 和卫星影像生成真实地形3.1 准备数据:你需要哪两个文件,从哪里获得BlenderGIS 最擅长处理的输入是覆盖同一区域的 GeoTIFF 高程数据和 GeoTIFF 影像数据,理想情况下两者范围完全一致,分辨率可以不同。高程数据控制了地形的起伏,影像数据决定了表面的颜色和纹理。两者缺一不可,没有高程,地形是平的;没有影像,地形是灰色的。常见做法是从公开数据源获取高程(例如 SRTM 数据),再配合公开影像服务下载底图,也可以自己用无人机正射影像做。拿到数据后第一件事是确认坐标系一致。在 QGIS 里打开两个文件的属性,看它们的 CRS 标识符是否相同。如果不一致,必须先用 QGIS 或 GDAL 重投影成同一个坐标系再导入。很多人第一次使用时直接导入某省范围的 DEM,又导入一份网络底图,结果地形网格急剧扭曲,原因就是坐标系统不一致。# 用 GDAL 快速检查两个 TIFF 的投影信息 gdalinfo dem.tif | grep -E "AUTHORITY|PROJCS|GEOGCS" gdalinfo ortho.tif | grep -E "AUTHORITY|PROJCS|GEOGCS"如果两条命令输出的 AUTHORITY 行不一致,则需要重投影。常见的重投影操作是使用gdalwarp,把影像数据重投影到高程数据相同的坐标系下,同时重采样。我通常用-r bilinear保留平滑度,因为最近邻法在影像上容易产生锯齿边缘。# 将 ortho.tif 重投影为与 dem.tif 相同的坐标系统 gdalwarp -overwrite -t_srs "EPSG:32650" -r bilinear -of GTiff ortho.tif ortho_reprojected.tif这里的EPSG:32650只是示意,实际操作时应该替换成gdalinfo dem.tif查到的具体 EPSG 编号。-r bilinear代表双线性插值,对影像数据来说画质损失小,对高程数据则应该用-r cubicspline来获得更平滑的地表。这个步骤看似繁琐,但它是后续一切操作的基石,做完这一步,你的两个文件现在处于同一个地理空间参考系里了。3.2 导入高程数据:从 2D 栅格到 3D 网格的关键一步启动插件面板后,找到高程导入按钮,通常命名为"导入 DEM"或"高程栅格"。点击后会弹出文件选择窗口,选择准备好的 dem.tif。导入时面板会让你选择采样步长(每个顶点间隔多少像素采样一个点),这一步决定了网格精度。默认值可能是 10,含义是每隔 10 个像素取一个高程值生成顶点,值越小网格越精细,但顶点数会平方级增长。我实践的典型参数是,对于一块 5 公里见方的区域,原始 DEM 分辨率 30 米,采样步长设为 4 到 6,生成网格约 40 万面,在普通笔记本上滚动和编辑仍然流畅。如果你要做电影级地形特写,可以设成 1 或 2,但建议先设成步长 10 跑一次流程,确认数据和方向无误后再细分。导入后地形可能呈现两种情况:一是扁平的圆形方块,二是高度范围只有零点几米的“平板”。前者通常是坐标系问题,后者是 Blender 默认缩放比例和地理数据之间的单位错配。高程值单位通常是米,但网格的 X、Y 坐标可能是经纬度,1 个单位的经纬度约为 111 公里,而高程只有几百米,所以视觉上完全压扁。解决方式是调整地形对象的缩放,在导入界面或者在网格上应用Z轴缩放系数。当你发现地形整体像一个纸片时,选中网格对象,在右侧属性栏的对象变换里找到缩放 Z 轴,手动输入 10 到 100 不等的系数并回车。这种做法是临时性的,如果你需要精确的 1:1 比例地形,不能靠缩放 Z 轴,而是要正确处理坐标变换参数,下一章会详细展开。3.3 叠加卫星影像:让地形有皮肤,而不是一张灰模高程网格生成后,场景里出现的是一个灰白相间的起伏表面。接下来把影像贴上去。在插件面板找到“导入影像”或“添加底图”按钮,选择 3.1 节准备的 ortho_reprojected.tif。插件会自动对这个影像和已存在的网格做范围匹配,然后生成一个新的材质,把影像作为基础色纹理绑定到地形网格上。如果你不需要材质系统,只想要一个纯纹理坐标绑定关系,也可以手动做:先导入地形网格,再导入影像为参考图,然后在着色器编辑器里用纹理坐标节点连接参考图像。BlenderGIS 的优势在于它自动计算了 UV 坐标。因为地形网格是基于 DEM 经纬度生成的,每个顶点都有经纬度坐标信息,插件能精确地将影像像素映射到对应的顶点上,不需要手工 UV 展开。导入后如果看到纹理错位、拉伸或重复,先检查 3.1 节两个文件的范围一致性。我再三强调这个原因,是因为 80% 以上的纹理贴歪案例源自数据范围不匹配或坐标系不一致。其次检查影像分辨率,如果影像太模糊,纹理在地表拉近后会糊成一片,建议用更高分辨率的底图。卫星影像 URL 下载服务一般有清晰度级别可供选择。4. 坐标系统对齐:从经纬度到 Blender 世界坐标的距离与比例换算4.1 为什么所有地形看起来不是太大就是太小:坐标缩放的本质Blender 不是 GIS 工具,它内部使用一个抽象世界坐标系统,单位可以自由解释为米、厘米或者任何自定义长度。BlenderGIS 导入地理数据时,直接把经纬度当作平面 X、Y 坐标输入,经纬度 1 度大约等于 111 公里,在 Blender 中就变成了 111000 单位的距离。如果你导入的是带地理坐标的真实数据,格子面在默认视图中会拉伸到无法操作的状态。这时插件给出的解决方案是让用户指定一个缩放系数,把经纬度单位换算到米制单位。常见操作是在导入面板的“自定义比例”参数里输入 0.01 到 0.1 之间的值。如果数据原本是投影坐标(如 UTM 坐标),坐标值本身已经是米,不设置缩放系数也能正确显示。很多教程推荐直接修改场景单位,但这里有个玄学点:即使你修改了 Blender 的单位制,插件内部坐标计算仍基于原始值,不会自动适配。所以最佳实践是:若数据是经纬度,导入时明确设置比例因子;若数据是投影坐标,比例因子保持 1.0。在规划模拟项目时,我通常会在导入高程后先截个图,对比参考点之间的距离,确认比例正确再继续做影像叠加。4.2 把 Blender 场景里的地标点换算成经纬度:反向验证方法当你只拿到了某个建筑角的经纬度坐标,想摆一个空对象在那个位置,直接输入经纬度是没有意义的。需要把经纬度转成 Blender 世界坐标。假设场景中心对应某点经度为 lon0,纬度为 lat0,来自 DEM 文件信息;场景中某个位置 X、Y 所对应的经纬度换算公式是:经度 = lon0 + X / (111320 * cos(lat0)),纬度 = lat0 + Y / 110540。import math # 假设 DEM 左下角坐标(或场景原点对应坐标)已知,单位:度 lon0 = 116.3912 # 用你实际的左下角经度替换 lat0 = 39.9072 # 用你实际的左下角纬度替换 # 场景里某个物体的世界坐标 X, Y X = 123.4 Y = 567.8 # 度到米的换算系数 lat_rad = math.radians(lat0) lon_meter = 111320.0 * math.cos(lat_rad) lat_meter = 110540.0 lon = lon0 + X / lon_meter lat = lat0 + Y / lat_meter print(f"对应的经纬度: {lon:.6f}, {lat:.6f}")这段脚本的作用是把 Blender 世界坐标反推回经纬度,当你要根据真实 POI 点摆放模型时极其有用。反过来,如果已知一个 POI 的经纬度,想得到它的 Blender 坐标,只需要把脚本里的公式反转一下,用 lon 和 lat 减去 lon0 和 lat0,再乘以各自对应的米制系数。公式里的 111320 和 110540 是地球在赤道附近每度对应的米数,由于地球不是正球体,实际上不同纬度略有差异,但在局部小范围使用误差可以忽略。一个容易出错的点是:如果 Blender 场景原点不在 DEM 左下角而在中心,或者你移动过地形网格的位置,基准点 lon0、lat0 也需要相应调整。我的习惯是:导入 DEM 后立刻在网格边缘放置一个空对象记录原点位置,后续所有转换都参照这个空对象。坐标换算正确与否的验证方法很简单:在场景里放置一个已知经纬度的标记点,用脚本计算结果和真实值对比,偏差应小于 1 米。4.3 导入后所有网格出现在奇怪位置的排查思路地形区域不大时,通常会直接出现在 Blender 原点附近;如果 DEM 区域覆盖很大,网格可能出现在离原点几万公里外的地方。这不是 Bug,而是坐标真实反映。此时只需要选中网格,右键菜单里选择“吸附到游标”或手动把原点设置在地理范围中心即可。注意:移动网格后,之前设置的基准点坐标也会失效,需要重新记录。另一种情况是地形网格正常生成,但后续导入的矢量建筑轮廓(Shapefile)偏移几个街区。这种现象几乎都与两个数据源的投影基准面不一致有关,比如一个用的是 WGS84,另一个用了 GCJ02 坐标系。业界常用 GCJ02 坐标系是出于加密偏移的需求,如果你手里的 Shapefile 是这个坐标系,直接用会偏移几百米,必须通过专业转换函数转换后才可使用。判断坐标系是否正确有一个简单粗暴的办法:在插件里导入同样的数据两次,一次按原始坐标,一次强行指定为 WGS84,看哪个和底图叠加得齐。注意强行指定坐标系的方法只用来做诊断,不能作为正常流程。如果你在生产流程里发现某区域数据永远对不齐,先检查文件属性,而不是盲调比例因子。5. 避坑手册:我用这个流程翻过的 5 次车,以及后悔药配方5.1 导入后地形像被揉成一团的纸:怪网格细分太大现象:生成的地形网格面数爆炸,滚动视口时卡死,内存占用几个 G。原因:导入时采样步长设得太小,比如设为 1,同时对一块大范围 DEM 操作。我某次处理一块涵盖 40 公里范围的 DEM 时设成 2,直接生成上亿面。很多开发者一开始没意识到,步长是采样间隔,不是分辨率,设成 2 意味着每隔一个像素生成一个顶点,10 米分辨率的 DEM 就变成每 10 米一个顶点,这远超视觉需求。解决:先用大范围粗略构型,确定工作区再局部精细。技巧是:在插件面板里限制导入范围(如果有范围裁剪工具),或者先用 QGIS 把 DEM 裁剪到你真正需要的区域。如果不幸已经生成了超大网格,用 Blender 的减面修改器一次性降到 10% 的面数,操作在修改器属性里,选“坍陷”模式,迭代次数设 5 左右。5.2 影像糊成马赛克但 DEM 文件本身清晰:投影重采样设错了插值方法现象:同一块区域用纹理贴图后,边界像被刀子切过一样错位,细节丢失严重。原因:3.1 节重投影时用了默认最近邻采样,对于高程数据可以用,但影像数据会丢失颜色过渡信息,产生锯齿和错位。解决:重投影影像时务必使用-r bilinear或-r lanczos。命令改为:gdalwarp -r lanczos -t_srs "EPSG:32650" ortho.tif ortho_reproj.tif使用 lanczos 虽然计算慢,但纹理质量最好。如果你已经导入了网格和纹理,不必重新导入全部,只需重新生成影像文件并重新贴一次纹理即可,插件会按 UV 自动对齐。5.3 换个电脑后 BlenderGIS 面板显示但按钮全灰:缺少了环境变量现象:在自己机器上一切正常,到某公司或同事的电脑上,插件功能菜单全部变灰,点击无响应。原因:另一台电脑缺少 GDAL 或者其他地理库,插件在启动时尝试加载失败,但 Blender 因为错误拦截机制只显示禁用按钮。解决:检查系统命令行能否运行gdalinfo --version。如果这个命令报错,就是 GDAL 缺失。在 Linux 上安装那个libgdal-dev即可,Mac 上建议用 Homebrew 安装gdal。Windows 上更麻烦一点,需要确保 Blender 用的是同一个 Python 环境且安装了rasterio等库。凡是插件按钮变灰,不要怀疑 Blender 本身,直接排查依赖。5.4 底图和地形重叠但明显是镜像关系:栅格方向约定坑现象:卫星影像在天上看起来正常,贴到地形上后山脊走向却是左右翻转的,河流方向变了。原因:GeoTIFF 里影像行存储方向可能与 Blender 纹理坐标轴方向相反,尤其来自不同数据源的影像容易出现这种情况。解决:在导入影像后,如果发现地形纹理镜面翻转,在着色器编辑器里找到纹理坐标节点,把 X 轴换成 -X 接线,也就是把“Texture Coordinate”节点的 X 输出乘以 -1 后再接入图片纹理的 Vector 输入。这种修法是局部修补,如果整个工程都换了数据源,建议在 QGIS 里重新裁剪或翻转一次再导入。5.5 加载某些区域的 DEM 时只有高程没有横向范围:数值溢出现象:特定区域的高程能生成网格,但网格是 100 米长、100 米宽的很小的方块,和 DEM 实际覆盖范围不符。原因:这个坑常出现在北极或南极附近区域,经纬度投影在极区会产生极大坐标值,造成浮点精度丢失,插件默认按短整型处理坐标时溢出。解决:尽量避免直接导入极区高纬度数据。如果必须做,先将 DEM 用gdalwarp转成 UTM 投影(北极区域用 EPSG:32661 等极地方位投影),再导入到插件中。UTM 坐标数值较小,浮点安全。这个坑比较偏门,但一旦遇到根本无法通过调整参数解决,只有改变投影路径一条路。6. 进阶玩法:从地形到场景——一键堆叠矢量建筑与场景性能优化地形做出来后,下一步通常是往上面摆建筑。BlenderGIS 提供了矢量数据导入功能,可直接读取 Shapefile 的面要素,把每个建筑轮廓拉伸成三维体块。在导入时你需要指定一个高度字段,Shapefile 属性表里通常有楼层数或高度列。如果没有高度字段,插件也可以用区域面积估算一个默认高度。实际操作中,我在某模拟项目中的流程是:从开放数据源获取该区域的建筑轮廓 Shapefile,使用 QGIS 裁剪到 DEM 相同范围,然后用插件的矢量导入功能载入。导入后面板询问高度字段,选择楼层数字段,然后输入层高(比如 3 米),插件会生成每个建筑轮廓对应的立方体,再配合一组随机种子来让高度产生微小变化,细节瞬间丰富起来。若不手动指定材质,建筑模型默认是白色材质,你可以用材质分配工具按建筑高度区间上色,比如高层红色、中层黄色、低层灰色,这样产出的图在视觉表达上专业非常多。场景文件变大之后,性能是核心瓶颈。我习惯在完成地形纹理后立即给地形添加一个减面修改器,并冻结为最终网格。不要保留原始超精细网格然后再复制多个,两个相似网格会耗尽显存。对于建筑,将每个建筑单独的物体合并成一个实例化集合,总共用一个几何实例节点引用,因为同类立方体的实例化能节省大量显存。如果你在场景里放几百栋建筑,用集合实例而不是直接放置物体,操作流畅度能提升数倍。树木、路灯、道路标线等小物件不需要真实地理坐标,只需要按照地面网格的 UV 或者顶点位置进行分布。使用粒子系统是最简单的办法:新建一个平面作为发射源,调整粒子数量并约束到顶点或面中心,然后指定一棵树为粒子物体。通过计算地面坡度来确定树的朝向,坡度大于某阈值的区域不生长树。这一步和纯地信无关,但在最终效果呈现上差异巨大。我始终建议保持一个习惯:每次地形调整完比例,保存一份坐标基准记录,用空文本对象放在场景原点,记录导入 DEM 的坐标系、原点经纬度和比例因子。几周后再打开工程,你或者任何接手的人都能快速定位坐标问题。尤其是当你从外部拿到新的辅助数据时,这份基准能帮你判断到底哪个环节出错,而不是漫无目的地调半天参数。这套工作流能不能跑通,关键取决于数据准备是否规范。只要你愿意先在数据上花 20 分钟检查坐标系、范围、分辨率,后面的建模流程几乎不会浪费时间。希望这些经验能帮到你少走一些我走过的弯路。本文还有配套的精品资源,点击获取
简介:BlenderGIS是一个在Blender与地理数据之间搭建桥梁的插件,面向3D建模师、GIS开发者以及需要将地形、卫星影像或OSM数据引入三维场景的用户。压缩包内共131个文件,以78个Python脚本为插件核心代码,另含32个SVG界面图标、13个PNG预览图、2个Markdown说明文档以及许可证、配置等文件,整体仅402KB,结构紧凑。已有6855人学习,常用于快速实现地理参考相机、激光雷达点云、地形高程与OpenStreetMap数据的可视化。借助附带的README和示例资源,可了解各模块的调用方式,并在此基础上扩展自定义导入流程,适合作为地理空间数据可视化入门或Blender插件开发的参考。1. 3D-BlenderGIS.zip 是什么:一条从二维地图到三维地形的直通车道做可视化、游戏关卡、数字孪生或者航拍路线规划时,最头疼的不是建模本身,而是把真实世界的地理数据搬进三维软件。手动把高程点描成网格、再把卫星图一张张贴上去,等于用石器时代的工具干农业时代的活儿。这个 zip 包里的东西,就是用来解决这个问题的一整套桥梁方案:它让 Blender 直接读取常见地理数据格式(GeoTIFF、Shapefile、栅格影像),把经纬度、海拔、建筑轮廓转成可编辑的网格和材质,几秒钟内生成一个带有真实地形起伏和影像纹理的三维地表。这个方案最打动我的点是它的定位:不是把 Blender 变成一个 GIS 软件,而是把 GIS 数据翻译成 Blender 能听懂的语言。你做倾斜摄影、白模、地形漫游、流域分析可视化,它都能作为数据入口;它不会替你完成分析,但能把分析结果以三维形式呈现出来。适合的人群很明确——用 Blender 做地信相关可视化但又不想学整套 QGIS 建模流程的开发者,以及需要快速出地形原型给客户确认方向的从业者。我最早用它是为了做一个某区域的山体滑坡模拟 Demo,当时手上只有一份 GeoTIFF 高程和一个航拍影像。从安装到生成带纹理的地形,只花了一个小时,而以前手动建网格至少需要一整天。接下来的内容会把这套流程完整走一遍,包括安装、操作、参数设置和最容易翻车的地方。2. 安装与环境准备:从 zip 包到 Blender 里出现一个能用面板2.1 安装流程:不是把 zip 塞进 Blender 就完事拿到这个 zip 之后,最常见的翻车是把整个压缩包直接拖进 Blender。Blender 的插件安装机制要求的是压缩包内包含符合规范的插件目录结构,也就是addons/某个名字/__init__.py这种布局。正确的做法是在 Blender 的菜单栏里走:编辑 → 偏好设置 → 插件 → 右上角下拉箭头 → 从磁盘安装,然后在弹出的文件窗口里直接选中这个 zip 文件本身,不用提前解压。# 如果你喜欢用脚本安装,也可以在 Blender 的 Python 控制台里执行 import addon_utils import bpy # 启用插件,addon_name 需要替换成解压后实际目录名 addon_utils.enable("blender_gis", default_set=True, persistent=True) bpy.ops.wm.save_userpref()这段代码第一行导入的是 Blender 内部的插件管理工具,不需要用 pip 安装任何东西;第二行启用插件并把它写入用户偏好,这样下次启动 Blender 就不需要重新启用。运行完到偏好设置里确认一下该插件名称前出现了勾选框,如果没出现,多半是 zip 结构不对,先把 zip 解压到本地,看是不是有一层嵌套目录。常见情况是解压出来是某文件夹/某个名字/__init__.py,而 Blender 要求的是直接面对某个名字/__init__.py这级目录,此时把内层目录再压成 zip 即可。2.2 运行环境与前置依赖:你不需要 QGIS,但要有 GPU 哪怕很弱BlenderGIS 核心功能依赖的只有 Blender 本身,以及系统里能读取 GeoTIFF 的基础库。Blender 自带完整的 TIFF 支持,所以这一步通常不需要额外配置。如果你在 Windows 上使用,建议保持 Python 环境是 Blender 内置版本,不要单独安装其他 Python,避免库冲突。在项目实践中,某开发者在 Linux 服务器上跑过同样的流程,需要额外安装的是系统级的libgdal用于处理投影转换,这个在大多数发行版仓库里都能直接装。# Linux 下可能需要的基础库,按发行版差异包名略有不同 sudo apt install libgdal-dev gdal-bin这句命令带来的不止是 GDAL 命令行工具,更重要的是让 Blender 内部调用的底层库能识别各类投影坐标信息。如果你只是在本机做地形可视化,不涉及跨投影转换,这步可以跳过;但如果你要导入的数据投影不是常规的经纬度,比如 UTM 分区投影,依赖不装,导入后地形会错位得离谱。还有一个容易被忽略的检查点:Blender 版本必须大于 2.8,插件在早期版本上的行为完全不同。2.3 面板长什么样:激活后你的 3D 视口多了什么正确安装后,按 N 键展开右侧工具栏,会看到一个新标签页。这个标签页里通常有地形导入、影像导入、对象导出、坐标设置几个组。初次使用建议先别急着导入数据,打开几何节点编辑器确认没有报错提示,然后在场景属性里检查单位设置。Blender 默认单位是米,但地理坐标里经常用到度、千米,如果不统一单位,导入的网格会大得吓人或者小得看不见。接下来我会用一个具体工作流说明每个参数在实际中该设成什么,但在此之前,记住一个心法:这个插件的核心思维是把真实世界坐标换算成 Blender 的世界坐标,所有参数设置都围绕坐标变换进行。你不需要理解底层矩阵计算,但必须知道它有一个坐标缩放参数,而且这个参数极大影响场景比例,后面会有单独一章讲述如何调整。3. 第一次跑通完整流程:用高程 GeoTIFF 和卫星影像生成真实地形3.1 准备数据:你需要哪两个文件,从哪里获得BlenderGIS 最擅长处理的输入是覆盖同一区域的 GeoTIFF 高程数据和 GeoTIFF 影像数据,理想情况下两者范围完全一致,分辨率可以不同。高程数据控制了地形的起伏,影像数据决定了表面的颜色和纹理。两者缺一不可,没有高程,地形是平的;没有影像,地形是灰色的。常见做法是从公开数据源获取高程(例如 SRTM 数据),再配合公开影像服务下载底图,也可以自己用无人机正射影像做。拿到数据后第一件事是确认坐标系一致。在 QGIS 里打开两个文件的属性,看它们的 CRS 标识符是否相同。如果不一致,必须先用 QGIS 或 GDAL 重投影成同一个坐标系再导入。很多人第一次使用时直接导入某省范围的 DEM,又导入一份网络底图,结果地形网格急剧扭曲,原因就是坐标系统不一致。# 用 GDAL 快速检查两个 TIFF 的投影信息 gdalinfo dem.tif | grep -E "AUTHORITY|PROJCS|GEOGCS" gdalinfo ortho.tif | grep -E "AUTHORITY|PROJCS|GEOGCS"如果两条命令输出的 AUTHORITY 行不一致,则需要重投影。常见的重投影操作是使用gdalwarp,把影像数据重投影到高程数据相同的坐标系下,同时重采样。我通常用-r bilinear保留平滑度,因为最近邻法在影像上容易产生锯齿边缘。# 将 ortho.tif 重投影为与 dem.tif 相同的坐标系统 gdalwarp -overwrite -t_srs "EPSG:32650" -r bilinear -of GTiff ortho.tif ortho_reprojected.tif这里的EPSG:32650只是示意,实际操作时应该替换成gdalinfo dem.tif查到的具体 EPSG 编号。-r bilinear代表双线性插值,对影像数据来说画质损失小,对高程数据则应该用-r cubicspline来获得更平滑的地表。这个步骤看似繁琐,但它是后续一切操作的基石,做完这一步,你的两个文件现在处于同一个地理空间参考系里了。3.2 导入高程数据:从 2D 栅格到 3D 网格的关键一步启动插件面板后,找到高程导入按钮,通常命名为"导入 DEM"或"高程栅格"。点击后会弹出文件选择窗口,选择准备好的 dem.tif。导入时面板会让你选择采样步长(每个顶点间隔多少像素采样一个点),这一步决定了网格精度。默认值可能是 10,含义是每隔 10 个像素取一个高程值生成顶点,值越小网格越精细,但顶点数会平方级增长。我实践的典型参数是,对于一块 5 公里见方的区域,原始 DEM 分辨率 30 米,采样步长设为 4 到 6,生成网格约 40 万面,在普通笔记本上滚动和编辑仍然流畅。如果你要做电影级地形特写,可以设成 1 或 2,但建议先设成步长 10 跑一次流程,确认数据和方向无误后再细分。导入后地形可能呈现两种情况:一是扁平的圆形方块,二是高度范围只有零点几米的“平板”。前者通常是坐标系问题,后者是 Blender 默认缩放比例和地理数据之间的单位错配。高程值单位通常是米,但网格的 X、Y 坐标可能是经纬度,1 个单位的经纬度约为 111 公里,而高程只有几百米,所以视觉上完全压扁。解决方式是调整地形对象的缩放,在导入界面或者在网格上应用Z轴缩放系数。当你发现地形整体像一个纸片时,选中网格对象,在右侧属性栏的对象变换里找到缩放 Z 轴,手动输入 10 到 100 不等的系数并回车。这种做法是临时性的,如果你需要精确的 1:1 比例地形,不能靠缩放 Z 轴,而是要正确处理坐标变换参数,下一章会详细展开。3.3 叠加卫星影像:让地形有皮肤,而不是一张灰模高程网格生成后,场景里出现的是一个灰白相间的起伏表面。接下来把影像贴上去。在插件面板找到“导入影像”或“添加底图”按钮,选择 3.1 节准备的 ortho_reprojected.tif。插件会自动对这个影像和已存在的网格做范围匹配,然后生成一个新的材质,把影像作为基础色纹理绑定到地形网格上。如果你不需要材质系统,只想要一个纯纹理坐标绑定关系,也可以手动做:先导入地形网格,再导入影像为参考图,然后在着色器编辑器里用纹理坐标节点连接参考图像。BlenderGIS 的优势在于它自动计算了 UV 坐标。因为地形网格是基于 DEM 经纬度生成的,每个顶点都有经纬度坐标信息,插件能精确地将影像像素映射到对应的顶点上,不需要手工 UV 展开。导入后如果看到纹理错位、拉伸或重复,先检查 3.1 节两个文件的范围一致性。我再三强调这个原因,是因为 80% 以上的纹理贴歪案例源自数据范围不匹配或坐标系不一致。其次检查影像分辨率,如果影像太模糊,纹理在地表拉近后会糊成一片,建议用更高分辨率的底图。卫星影像 URL 下载服务一般有清晰度级别可供选择。4. 坐标系统对齐:从经纬度到 Blender 世界坐标的距离与比例换算4.1 为什么所有地形看起来不是太大就是太小:坐标缩放的本质Blender 不是 GIS 工具,它内部使用一个抽象世界坐标系统,单位可以自由解释为米、厘米或者任何自定义长度。BlenderGIS 导入地理数据时,直接把经纬度当作平面 X、Y 坐标输入,经纬度 1 度大约等于 111 公里,在 Blender 中就变成了 111000 单位的距离。如果你导入的是带地理坐标的真实数据,格子面在默认视图中会拉伸到无法操作的状态。这时插件给出的解决方案是让用户指定一个缩放系数,把经纬度单位换算到米制单位。常见操作是在导入面板的“自定义比例”参数里输入 0.01 到 0.1 之间的值。如果数据原本是投影坐标(如 UTM 坐标),坐标值本身已经是米,不设置缩放系数也能正确显示。很多教程推荐直接修改场景单位,但这里有个玄学点:即使你修改了 Blender 的单位制,插件内部坐标计算仍基于原始值,不会自动适配。所以最佳实践是:若数据是经纬度,导入时明确设置比例因子;若数据是投影坐标,比例因子保持 1.0。在规划模拟项目时,我通常会在导入高程后先截个图,对比参考点之间的距离,确认比例正确再继续做影像叠加。4.2 把 Blender 场景里的地标点换算成经纬度:反向验证方法当你只拿到了某个建筑角的经纬度坐标,想摆一个空对象在那个位置,直接输入经纬度是没有意义的。需要把经纬度转成 Blender 世界坐标。假设场景中心对应某点经度为 lon0,纬度为 lat0,来自 DEM 文件信息;场景中某个位置 X、Y 所对应的经纬度换算公式是:经度 = lon0 + X / (111320 * cos(lat0)),纬度 = lat0 + Y / 110540。import math # 假设 DEM 左下角坐标(或场景原点对应坐标)已知,单位:度 lon0 = 116.3912 # 用你实际的左下角经度替换 lat0 = 39.9072 # 用你实际的左下角纬度替换 # 场景里某个物体的世界坐标 X, Y X = 123.4 Y = 567.8 # 度到米的换算系数 lat_rad = math.radians(lat0) lon_meter = 111320.0 * math.cos(lat_rad) lat_meter = 110540.0 lon = lon0 + X / lon_meter lat = lat0 + Y / lat_meter print(f"对应的经纬度: {lon:.6f}, {lat:.6f}")这段脚本的作用是把 Blender 世界坐标反推回经纬度,当你要根据真实 POI 点摆放模型时极其有用。反过来,如果已知一个 POI 的经纬度,想得到它的 Blender 坐标,只需要把脚本里的公式反转一下,用 lon 和 lat 减去 lon0 和 lat0,再乘以各自对应的米制系数。公式里的 111320 和 110540 是地球在赤道附近每度对应的米数,由于地球不是正球体,实际上不同纬度略有差异,但在局部小范围使用误差可以忽略。一个容易出错的点是:如果 Blender 场景原点不在 DEM 左下角而在中心,或者你移动过地形网格的位置,基准点 lon0、lat0 也需要相应调整。我的习惯是:导入 DEM 后立刻在网格边缘放置一个空对象记录原点位置,后续所有转换都参照这个空对象。坐标换算正确与否的验证方法很简单:在场景里放置一个已知经纬度的标记点,用脚本计算结果和真实值对比,偏差应小于 1 米。4.3 导入后所有网格出现在奇怪位置的排查思路地形区域不大时,通常会直接出现在 Blender 原点附近;如果 DEM 区域覆盖很大,网格可能出现在离原点几万公里外的地方。这不是 Bug,而是坐标真实反映。此时只需要选中网格,右键菜单里选择“吸附到游标”或手动把原点设置在地理范围中心即可。注意:移动网格后,之前设置的基准点坐标也会失效,需要重新记录。另一种情况是地形网格正常生成,但后续导入的矢量建筑轮廓(Shapefile)偏移几个街区。这种现象几乎都与两个数据源的投影基准面不一致有关,比如一个用的是 WGS84,另一个用了 GCJ02 坐标系。业界常用 GCJ02 坐标系是出于加密偏移的需求,如果你手里的 Shapefile 是这个坐标系,直接用会偏移几百米,必须通过专业转换函数转换后才可使用。判断坐标系是否正确有一个简单粗暴的办法:在插件里导入同样的数据两次,一次按原始坐标,一次强行指定为 WGS84,看哪个和底图叠加得齐。注意强行指定坐标系的方法只用来做诊断,不能作为正常流程。如果你在生产流程里发现某区域数据永远对不齐,先检查文件属性,而不是盲调比例因子。5. 避坑手册:我用这个流程翻过的 5 次车,以及后悔药配方5.1 导入后地形像被揉成一团的纸:怪网格细分太大现象:生成的地形网格面数爆炸,滚动视口时卡死,内存占用几个 G。原因:导入时采样步长设得太小,比如设为 1,同时对一块大范围 DEM 操作。我某次处理一块涵盖 40 公里范围的 DEM 时设成 2,直接生成上亿面。很多开发者一开始没意识到,步长是采样间隔,不是分辨率,设成 2 意味着每隔一个像素生成一个顶点,10 米分辨率的 DEM 就变成每 10 米一个顶点,这远超视觉需求。解决:先用大范围粗略构型,确定工作区再局部精细。技巧是:在插件面板里限制导入范围(如果有范围裁剪工具),或者先用 QGIS 把 DEM 裁剪到你真正需要的区域。如果不幸已经生成了超大网格,用 Blender 的减面修改器一次性降到 10% 的面数,操作在修改器属性里,选“坍陷”模式,迭代次数设 5 左右。5.2 影像糊成马赛克但 DEM 文件本身清晰:投影重采样设错了插值方法现象:同一块区域用纹理贴图后,边界像被刀子切过一样错位,细节丢失严重。原因:3.1 节重投影时用了默认最近邻采样,对于高程数据可以用,但影像数据会丢失颜色过渡信息,产生锯齿和错位。解决:重投影影像时务必使用-r bilinear或-r lanczos。命令改为:gdalwarp -r lanczos -t_srs "EPSG:32650" ortho.tif ortho_reproj.tif使用 lanczos 虽然计算慢,但纹理质量最好。如果你已经导入了网格和纹理,不必重新导入全部,只需重新生成影像文件并重新贴一次纹理即可,插件会按 UV 自动对齐。5.3 换个电脑后 BlenderGIS 面板显示但按钮全灰:缺少了环境变量现象:在自己机器上一切正常,到某公司或同事的电脑上,插件功能菜单全部变灰,点击无响应。原因:另一台电脑缺少 GDAL 或者其他地理库,插件在启动时尝试加载失败,但 Blender 因为错误拦截机制只显示禁用按钮。解决:检查系统命令行能否运行gdalinfo --version。如果这个命令报错,就是 GDAL 缺失。在 Linux 上安装那个libgdal-dev即可,Mac 上建议用 Homebrew 安装gdal。Windows 上更麻烦一点,需要确保 Blender 用的是同一个 Python 环境且安装了rasterio等库。凡是插件按钮变灰,不要怀疑 Blender 本身,直接排查依赖。5.4 底图和地形重叠但明显是镜像关系:栅格方向约定坑现象:卫星影像在天上看起来正常,贴到地形上后山脊走向却是左右翻转的,河流方向变了。原因:GeoTIFF 里影像行存储方向可能与 Blender 纹理坐标轴方向相反,尤其来自不同数据源的影像容易出现这种情况。解决:在导入影像后,如果发现地形纹理镜面翻转,在着色器编辑器里找到纹理坐标节点,把 X 轴换成 -X 接线,也就是把“Texture Coordinate”节点的 X 输出乘以 -1 后再接入图片纹理的 Vector 输入。这种修法是局部修补,如果整个工程都换了数据源,建议在 QGIS 里重新裁剪或翻转一次再导入。5.5 加载某些区域的 DEM 时只有高程没有横向范围:数值溢出现象:特定区域的高程能生成网格,但网格是 100 米长、100 米宽的很小的方块,和 DEM 实际覆盖范围不符。原因:这个坑常出现在北极或南极附近区域,经纬度投影在极区会产生极大坐标值,造成浮点精度丢失,插件默认按短整型处理坐标时溢出。解决:尽量避免直接导入极区高纬度数据。如果必须做,先将 DEM 用gdalwarp转成 UTM 投影(北极区域用 EPSG:32661 等极地方位投影),再导入到插件中。UTM 坐标数值较小,浮点安全。这个坑比较偏门,但一旦遇到根本无法通过调整参数解决,只有改变投影路径一条路。6. 进阶玩法:从地形到场景——一键堆叠矢量建筑与场景性能优化地形做出来后,下一步通常是往上面摆建筑。BlenderGIS 提供了矢量数据导入功能,可直接读取 Shapefile 的面要素,把每个建筑轮廓拉伸成三维体块。在导入时你需要指定一个高度字段,Shapefile 属性表里通常有楼层数或高度列。如果没有高度字段,插件也可以用区域面积估算一个默认高度。实际操作中,我在某模拟项目中的流程是:从开放数据源获取该区域的建筑轮廓 Shapefile,使用 QGIS 裁剪到 DEM 相同范围,然后用插件的矢量导入功能载入。导入后面板询问高度字段,选择楼层数字段,然后输入层高(比如 3 米),插件会生成每个建筑轮廓对应的立方体,再配合一组随机种子来让高度产生微小变化,细节瞬间丰富起来。若不手动指定材质,建筑模型默认是白色材质,你可以用材质分配工具按建筑高度区间上色,比如高层红色、中层黄色、低层灰色,这样产出的图在视觉表达上专业非常多。场景文件变大之后,性能是核心瓶颈。我习惯在完成地形纹理后立即给地形添加一个减面修改器,并冻结为最终网格。不要保留原始超精细网格然后再复制多个,两个相似网格会耗尽显存。对于建筑,将每个建筑单独的物体合并成一个实例化集合,总共用一个几何实例节点引用,因为同类立方体的实例化能节省大量显存。如果你在场景里放几百栋建筑,用集合实例而不是直接放置物体,操作流畅度能提升数倍。树木、路灯、道路标线等小物件不需要真实地理坐标,只需要按照地面网格的 UV 或者顶点位置进行分布。使用粒子系统是最简单的办法:新建一个平面作为发射源,调整粒子数量并约束到顶点或面中心,然后指定一棵树为粒子物体。通过计算地面坡度来确定树的朝向,坡度大于某阈值的区域不生长树。这一步和纯地信无关,但在最终效果呈现上差异巨大。我始终建议保持一个习惯:每次地形调整完比例,保存一份坐标基准记录,用空文本对象放在场景原点,记录导入 DEM 的坐标系、原点经纬度和比例因子。几周后再打开工程,你或者任何接手的人都能快速定位坐标问题。尤其是当你从外部拿到新的辅助数据时,这份基准能帮你判断到底哪个环节出错,而不是漫无目的地调半天参数。这套工作流能不能跑通,关键取决于数据准备是否规范。只要你愿意先在数据上花 20 分钟检查坐标系、范围、分辨率,后面的建模流程几乎不会浪费时间。希望这些经验能帮到你少走一些我走过的弯路。本文还有配套的精品资源,点击获取