资讯详情

b3dm转FBX实操:Blender 4.3中倾斜摄影模型单体化全流程

📅 2026/10/18 22:10:20 | 华诺云谱 👁 阅读
b3dm转FBX实操:Blender 4.3中倾斜摄影模型单体化全流程
前阵子有朋友丢给我一整套三维瓦片说是某个街区的高精度倾斜摄影成果文件后缀清一色是.b3dm。他在三维GIS平台里看得很爽可美术那边要的是 FBX还要求在 Blender 4.3 里把每栋楼单独拎出来——也就是常说的单体化。这条链路听起来不复杂真走一遍你就会发现拆包、格式转换、坐标修正、单体化导出每一步都埋着雷。这篇就把完整流程过一遍从 b3dm 结构讲到 FBX 导出重点放在 Blender 4.3 里的模型体检和单体化操作最后给出一些我实际踩坑后的建议。1. b3dm 这个容器到底装了什么为什么绕不开 FBX很多刚从 GIS 转过来做三维的朋友看到 b3dm 第一反应是这跟 glTF 是不是一回事。严格说b3dm 是 3D Tiles 标准里的一种瓦片容器全称 Batched 3D Model它并不是一种纯粹的模型格式。理解这一点后面所有转换逻辑就顺了。1.1 拆开 b3dm 的封装几何藏在 GLB 里属性挂在 batchTable 上b3dm 更像是一个快递盒外壳是 28 字节的二进制头里面装着一个完整的 GLB 文件盒子侧面还贴了标签叫 featureTable 和 batchTable。GLB 是 glTF 的二进制形态几何网格、材质、贴图、UV、骨架动画全都能塞进一个文件里便于快速加载。倾斜摄影生成的高精度三角网几乎都是靠 GLB 承载的。batchTable 则负责记录建筑材料属性比如建筑物 ID、高度、层数、面积甚至原始属性表的 JSON。这些属性的用途很关键如果你走的是 ID 单体化或属性单体化batchId 就是区分每一栋建筑的钥匙。但问题在于Blender 默认导入 GLB 时并不主动解析 b3dm 的 batchTable所以单体化时我们不能指望导入后自动有对象 ID这一点后面会详细说。28 字节 b3dm 头的字段顺序如下偏移 长度 说明 0 4 magic固定 b3dm 4 4 version目前是 1 8 4 byteLength整个 b3dm 文件字节数 12 4 featureTableJSONByteLength 16 4 featureTableBinaryByteLength 20 4 batchTableJSONByteLength 24 4 batchTableBinaryByteLength看到这里你应该明白了任何声称能从 b3dm 直接读模型的工具本质上做的都是把头剥掉把里面的 GLB 取出来。下面用 Python 标准库就能完成这一步import json import struct from pathlib import Path def b3dm_to_glb(input_path: Path, output_path: Path) - None: data input_path.read_bytes() if data[:4] ! bb3dm: raise ValueError(不是有效的 b3dm 文件) byte_length struct.unpack_from(I, data, 8)[0] ft_json_len struct.unpack_from(I, data, 12)[0] ft_bin_len struct.unpack_from(I, data, 16)[0] bt_json_len struct.unpack_from(I, data, 20)[0] bt_bin_len struct.unpack_from(I, data, 24)[0] start 28 ft_json_len ft_bin_len bt_json_len bt_bin_len glb data[start:byte_length] if glb[:4] ! bglTF: raise ValueError(b3dm 中没有找到内嵌 GLB) output_path.write_bytes(glb) # 批量转换目录下所有 b3dm tiles_dir Path(./tiles) out_dir Path(./glb_out) out_dir.mkdir(exist_okTrue) for b3dm_file in tiles_dir.glob(*.b3dm): b3dm_to_glb(b3dm_file, out_dir / (b3dm_file.stem .glb))这一段脚本是整条流水线的地基。实际处理几百个瓦片时我一般先跑一遍检查有没有文件头解析失败的情况——遇到过某些二次开发的软件会在 b3dm 头里塞扩展字段导致直接偏移出错这时候需要在命令行里打印 header 信息逐字节核对。1.2 为什么最终目标偏偏是 FBX同样的模型转 OBJ 也行、转 glTF 也行为什么大家都指定 FBX核心原因在于下游生态。FBX 是 Autodesk 体系下的通用交换格式Unity、Unreal、3ds Max、Maya、Blender 全都有成熟的原生支持。OBJ 虽然通用但只能存最基础的几何和贴图路径材质节点、物体层级、坐标轴约定这些信息基本全丢。glTF 在 Web 3D 和游戏引擎里确实更现代但它对 DCC 工具数字内容创作工具的适配目前还赶不上 FBX尤其是在动画分层、单位换算、命名空间保留这些细节上。所以当一个项目需要跨软件交接时FBX 几乎是最稳妥的中间格式。这里要补充一个反直觉的结论如果你手里已经拿到了 GLB我通常不建议再单独用命令行工具转一次 FBX 再导入 Blender。Blender 4.3 对 glTF/GLB 的原生导入已经非常成熟直接导入 GLB 再导出 FBX材质、UV、法线的保留率远高于中间经过一次通用转换器。换句话说标题里的转为 FBX放到整个流程的末端执行中间先用 GLB是更省心的做法。2. 转换路线选型别一上来就找一键工具很多人上来就想找一个b3dm 转 FBX的一键工具但这类工具往往存在两个问题一是对 b3dm 的 batchTable 支持很弱建筑属性在转换后就丢了二是自动生成的材质常常不符合下游软件预期导入 Blender 后还要重新指定贴图。所以与其找万能转换器不如先想清楚你要的是什么。2.1 三条主路线的对比我把实际操作中常见的方案列成一张表方便你根据项目情况选路线做法优点缺点A. Blender 中转拆出 GLB → Blender 导入 GLB → 处理完再导出 FBX材质保留最好能顺手做单体化和修复流程可控需要手动操作批量场景要写脚本B. 通用转换器拆出 GLB → 转成 FBX → 再导入 Blender适合纯批量流水线速度快材质节点容易丢法线可能翻转单位容易错C. GIS 工具箱直接用集成工具导出 FBX操作门槛低依赖具体版本单体化能力弱属性与网格的映射关系容易丢路线 B 对单个文件确实很快但当模型面数动辄几百万、纹理贴图还带透明通道时通用转换器生成的 FBX 往往会出现一堆材质球命名混乱导入 Blender 后还得重新整理省下的时间又赔回去了。所以只要不是一次性处理几百上千个文件我推荐路线 A。2.2 我实际采用的组合这次项目里有差不多 200 个 b3dm 瓦片但我只需要把其中重点区域合并成一个场景来做单体化。我的做法是先用上一章的 Python 脚本把所有 b3dm 批量拆成 GLB用 Blender 4.3 的 File Import glTF 2.0 导入全部 GLB在 Blender 里合并场景、修正坐标、做单体化、导出 FBX。有些瓦片属于相邻区域导入后会在同一个世界坐标下自动拼接。只要原数据的坐标系一致Blender 里导入后它们天然就在正确相对位置——这也是 GLB 导入的优势之一。关键提醒导入前先在 Blender 的 Scene Properties 里把单位设为米这决定了之后 FBX 导出的比例是否错乱。3. 拆包之后GLB 到 FBX 的两种通道当你已经拿到 GLB 文件下一步无非两条路要么先转成 FBX要么直接进 Blender。这里把两条路都讲清楚免得你在不同场景下走弯路。3.1 通道一直接在 Blender 里导成 FBX打开 Blender 4.3File Import glTF 2.0选中 GLB 后默认参数导入即可。场景里会生成一个或多个网格对象材质节点会自动创建 Principled BSDF 和对应的 Image Texture 节点。这时候什么都不用改直接 File Export FBX选好输出路径就能得到 FBX。这个通道的隐藏价值在二次处理你可以在导入后顺手把多余的相机、空物体删掉把法线重算一遍再导出。这些操作虽然不起眼却能避免 FBX 在别的软件里偏色、变黑或出现异物。注意导出 FBX 的默认参数Forward 为 -Z、Up 为 Y这套坐标约定正好匹配 Unity 和 Unreal如果下游是 3ds Max建议改成 Forward: -Y、Up: Z。3.2 通道二用命令行工具批量直转 FBX如果你手头有上百个 GLB 要快速转 FBX逐个打开 Blender 显然不现实。这种场景下我建议用脚本方式批量处理import bpy import sys glb_dir sys.argv[-2] fbx_dir sys.argv[-1] for glb_file in sorted(glb_dir.glob(*.glb)): bpy.ops.wm.read_factory_settings() bpy.ops.import_scene.gltf(filepathstr(glb_file)) fbx_name glb_file.stem .fbx bpy.ops.export_scene.fbx( filepathstr(fbx_dir / fbx_name), path_modeCOPY, embed_texturesTrue, use_mesh_modifiersTrue, apply_scale_optionsFBX_SCALE_UNITS, )这里有两个参数很关键embed_texturesTrue会把贴图直接嵌进 FBX 文件里避免交付后贴图路径失效path_modeCOPY则是把依赖文件复制到导出目录。如果你在 Linux 服务器上没有界面环境可以用如下命令跑blender -b -P batch_glb_to_fbx.py -- ./glb_dir ./fbx_dir注意blender -b是后台模式不会弹出任何窗口非常适合做批量流水线。最后得到的 FBX 已经是 Blender 处理过的材质、UV、坐标都不会有常见转换工具那么明显的损失。4. 导入 Blender 4.3 之后先别急着做单体化真正导入模型后80% 的精力都花在体检上。倾斜摄影模型不像手工建模它有非常典型的 GIS 特性坐标值巨大、单位可能是米也可能是度、网格存在大量冗余顶点、法线方向可能不统一。这些不解决单体化做着做着就会出现选不中想要的建筑或者分离后建筑一半黑脸的诡异现象。4.1 坐标飞点问题模型跑到几公里外怎么办b3dm 里的坐标通常来自投影坐标系或局部 ENU东-北-上坐标系。偏转后的坐标数值可能非常大比如 X 接近 500000 米。Blender 的网格顶点位置虽然支持双精度但很多操作和渲染管线依然基于单精度浮点一旦坐标太大模型会出现顶点抖动、雕刻效果差、选择面时高亮显示混乱等问题。解决办法是整体挪回原点。选中所有对象后进入编辑模式全选顶点在侧边栏的 Transform 面板里手动把 X、Y 减去一个固定偏移量。更推荐的做法是建立一个 Empty 作为父级把偏移量记在 Empty 上网格对象保持相对坐标。这样既保住了原始地理参考信息又让 Blender 操作顺畅。无论哪种方法记住偏移量导出 FBX 前或导入其他软件时再加回去。4.2 单位之坑FBX 的厘米和 Blender 的米这是所有跨格式流程里最容易踩、且后果最迷惑的坑。glTF 标准规定单位是米所以 GLB 直接导入 Blender 后 1 单位就是 1 米很省心。但 FBX 的历史包袱是 Autodesk 单位默认按厘米处理。如果你用命令行工具提前转了一次 FBX再导入 Blender 时就会看到模型被放大了 100 倍。在 Blender 4.3 的 FBX 导入面板里有两个相关选项Scale 和 Global Scale。遇到放大 100 倍的情况把 Global Scale 设为 0.01 即可恢复真实比例。但我更推荐你在流程里尽量让 GLB 作为真源用 Blender 导出 FBX 时在导出面板选择Scale: FBX Units Scale这样导出的 FBX 会自动把 1 米映射为 100 厘米下游软件拿到的实际尺寸不会变。4.3 材质与 UV 的检查清单导入 GLB 后先别急着关掉 Shader Editor。倾斜摄影模型的纹理一般是一张或几张大的图集Texture Atlas整个场景共享 UV 空间。这种纹理烘焙方式很常见所以单体化时不要随便重新展开 UV否则一张图集就会被拆得七零八落。检查清单如下材质球数量是否合理如果出现几十个同名的材质球需要考虑是否导入时把每栋楼拆成了独立对象。在 Shader Editor 里确认 Principled BSDF 有正确的 Base Color 输入而不是一张加载失败的纹理节点。如果模型显示为全灰去 Build 里看 Image Texture 节点的路径是否还在。GLB 通常是嵌入纹理一般不会丢但一旦走了b3dm → GLB → 转换工具 → FBX这条链路贴图路径就很容易失效。有透明区域比如玻璃幕墙的贴图检查 Alpha 通道是否被识别如果纯黑或纯白说明 Blending 模式和 Alpha 节点没有接对。做完这些检查再进入编辑模式全选网格按ShiftN重算法线。倾斜摄影数据经常出现法线翻转这一步能避免后面单体化分离出的建筑一面正常一面全黑。4.4 合并顶点和清理杂散面倾斜摄影 Mesh 是由大量三角面拼出来的顶点共享关系不一定健康。导入后在高密度区域可能出现面重叠、缝隙、孤立顶点。用Merge by Distance距离阈值设在 0.001 米左右能有效合并重叠顶点。注意距离阈值不要设太大否则会把相邻建筑的顶点也焊在一起反而不利于单体化。清理完顶点后用Mesh Clean Up Delete Loose删掉孤立顶点用Limited Dissolve合并共面三角形。这两个操作对整体面数有很明显的优化效果对单体化选面的帮助也很大——面片越少CtrlL选相连面的准确率越高。5. 单体化落地从一整块三角网到一栋栋独立对象单体化这个词在三维 GIS 里常被挂在嘴边但不同语境下指的东西不一样。我见过有人把单体化理解成画个框高亮一下也有人把它理解成把模型切割成一个个独立文件。在 Blender 里我们实际做的是后者也就是几何单体化让每栋建筑成为一个可以独立选中、编辑、导出的网格对象。5.1 三种单体化思路Blender 能做的是哪一种表格里做个对比单体化方式原理适合场景Blender 可行度切割单体化把属于同一建筑的三角面物理分割成独立对象需要独立编辑、导出模型可行本文讲这种属性单体化给每个三角面写入建筑 ID模型不切割保留原始 Mesh 完整性做属性查询部分可行需要扩展插件配合ID 单体化用透明辅助模型贴合建筑轮廓点击时关联属性WebGIS 平台做点击高亮不适合纯 Blender 流程需回到 GIS 平台大多数非 GIS 项目要的其实是切割单体化。因为美术不在乎你能不能点选他们只想把某栋楼拖进引擎里单独修改。所以本文的单体化均指在 Blender 中把建筑网格分离成独立对象。5.2 手动选面一个建筑一个建筑地挑出来导入并修好模型后进入编辑模式。在右上角的 Viewport 材质预览里打开带纹理的显示模式这时候你能清楚看到一栋栋建筑的轮廓。选择建筑顶部任意一个面然后按CtrlLSelect Linked就能选中与它相连的整个三角网区域。这个方法对付孤立的建筑基本没问题。但如果建筑之间通过墙面、廊道、地面共用顶点或者建筑底层是连通的商业裙房CtrlL会把好几栋楼一起选中。这类情况需要你先在编辑模式下把连接处切断找到相邻建筑之间的过渡面比如屋檐下的连廊手动选中这些面按X删除仅删面不删顶点破坏连通性后再重新选。这里有一个实用技巧选择建筑的大致范围时先用矩形框选B 键框出建筑所在区域再使用CtrlL去除误选的其他部分。倾斜摄影网格三角面密度极高纯手动逐个点选不现实框选加联动选择能省下很多时间。5.3 分离、命名、加属性三步整理输出对象选中一个建筑的完整网格后按P键选择Selection分离。此时这个建筑会从原场景中独立出来成为一个新对象。重复上述操作把所有需要单体化的建筑都分离出来。分离出来的对象需要做三件琐碎但重要的事重命名直接在 Outliner 里把对象名改成building_001、building_002这种规范的名字。如果数量很多用 Blender 的 Batch Rename 插件批量处理。设置原点选中对象右键 Set Origin Origin to Geometry。这样对象原点会落在几何重心方便后续在引擎里摆放和旋转。添加自定义属性在 Object Properties 面板最下方的 Custom Properties 里添加键值对比如height: 32.5、area: 1200、name: 社区服务中心。这些属性在导出 FBX 后大部分能被 Unity/Unreal 识别作为物体元数据保留下来。如果你有 batchTable 转出的 CSV 或 JSON 属性表可以在这一步按建筑 ID 手动或脚本化地把属性写进 Custom Properties。属性数值不要求多全能把建筑名称、层数、高度记录上交付时就能省掉大量口头沟通。5.4 屋顶和底面的处理倾斜摄影单体化后一般建筑底部是没有底面的——它和地面共用了网格分离时自然把底面留在了原场景。很多时候这无所谓放在地面上本来就看不见底面但如果要求模型在水面上或建筑需要单独展示就得补一个底面。补底面最快的方法是选中建筑底部边缘一整圈边界边Shift 键逐个选择或按G配合吸附然后用菜单Face Grid Fill生成网格封面。Grid Fill 对复杂轮廓生成的网格不一定漂亮但对大多数建筑来说一个平面已经够用。用AltM合并顶点到中心也能做三角扇形的底面效果因人而异。如果你想保持干净也可以按F键把边缘选中后直接填充一个 N-Gon 面。Blender 4.3 对 N-Gon 的处理很成熟导出游戏引擎时会自动转成三角面不影响使用。6. 导出 FBX 的参数细节和交付后最常见的三个问题单体化完成后最后一步是把整理好的建筑导出成 FBX。这一步的参数如果不注意前面所有努力会在导出瞬间被打回原形。6.1 导出面板推荐配置选中要导出的建筑对象File Export FBX我推荐的配置如下参数设置理由IncludeLimit to Selected Objects只导出选中的建筑避免把地皮和大场景一起塞给下游Object TypesMesh排除空物体、相机、灯光等无关对象Apply ScalingsFBX Units Scale保持 1 单位 1 米下游软件按 Autodesk 单位读取时不会差 100 倍Forward / Up-Z / Y匹配 Unity 和 Unreal 的默认坐标习惯Apply Transform开启消除对象级负缩放或旋转带来的隐患Path ModeCopy把贴图复制到 FBX 同级目录Embed Textures开启把纹理直接嵌入 FBX方便分发单个文件Use Mesh Modifiers开启如果有细分或清理修改器导出时应用效果其中 Embed Textures 这个开关我强烈建议交付外部团队时打开。虽然文件体积会变大但对方拿到 FBX 后不需要手动找贴图省下大量沟通成本。如果你做的是内部资产贴图统一走共享路径那么 Path Mode 选 Relative 也行。6.2 交付后常见问题排查每次导出交付后总会收到类似问题。我总结三个高频的附上排查思路模型方向不对建筑躺在地上歪着立起来。这通常是导出面板的 Forward/Up 设置和下游软件不一致。Unity/Unreal 默认用 -Z 作为前、Y 作为上Blender 默认也是这套但如果下游是 3ds Max需要改为 Forward: -Y、Up: Z。出问题先问对方软件是什么再对应调整。材质显示为紫红色或全灰。检查 FBX 同级目录是否有贴图文件。右键缺失纹理的材质球在 Image Texture 节点里手动重新指定路径即可。如果对方只有单个 FBX 文件那就要怪我没有开 Embed Textures。导入后尺寸巨大或缩成一点。Quick 检查在 Blender 里物体的实际大小选中对象查看 Dimensions 属性。如果原比例是 1:1说明对方软件的单位设置和 FBX 不一致设置对方软件单位为厘米或米即可。6.3 批量导出几十个建筑逐个导太慢用脚本如果单体化出几十栋楼不想一个个导出可以写一个 Blender Python 脚本在后台模式下自动遍历所有对象并导出import bpy import pathlib out_dir pathlib.Path(/output/fbx_buildings) out_dir.mkdir(parentsTrue, exist_okTrue) for obj in bpy.data.objects: if obj.type ! MESH or not obj.name.startswith(building_): continue # 先选中再进入导出 bpy.ops.object.select_all(actionDESELECT) obj.select_set(True) bpy.context.view_layer.objects.active obj export_path str(out_dir / (obj.name .fbx)) bpy.ops.export_scene.fbx( filepathexport_path, use_selectionTrue, apply_scale_optionsFBX_SCALE_UNITS, path_modeCOPY, embed_texturesTrue, )跑法依然是blender -b -P batch_export_fbx.py。这样每个建筑一个 FBX 文件文件名和对象名一致后续想要在引擎里跟属性表关联也方便。6.4 一根筋流程的代价为什么我不推荐先转 FBX 再导入 Blender最后聊一个纯经验层面的建议。不少人看到b3dm 转 FBX的步骤会直接搜转换工具转完再拉进 Blender然后发现模型不是大了 100 倍就是贴图全丢。这套流程兜兜转转每一步失败的判定成本都很高。与其这样不如接受Blender 中转的思路b3dm 拆成 GLBBlender 直接读 GLB把所有修复和单体化做完最后在导出节点统一输出 FBX。如果某个同事或客户认死理非要一个中间 FBX文件那就在 Blender 里导入 GLB 后立即再导出 FBX再回头把 FBX 导入检查一遍。这个中间 FBX 的质量比任何命令行转换库出来的都更可控。我在实际操作中发现单体化最耗时间的从来不是格式转换而是选面和清理几何。所以如果你不想在这上面花太多时间不妨先把原始模型的共享顶点合并到最小可接受程度再用框选加CtrlL的方式分离建筑。做几个项目后你会发现一套稳定的处理顺序比任何工具都重要拆包 → 导入 → 修坐标 → 清几何 → 单体化 → 导出。每个环节都用自己的经验校准一遍这条流水线才算真正跑通。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑