简介:这是一套专为Blender用户定制的Python插件工具包,面向游戏资源开发、3D建模师及Dark Engine(如《Thief》《System Shock》系列)老游戏MOD制作者,解决.e格式场景文件导入、AI网格导出及纹理兼容性处理等核心痛点。资源共19个文件,含3个核心Python脚本(import_e.py、export_bin.py、init.py)、1个Windows可执行文件convert.exe(用于图像格式转换)、12张操作界面截图(涵盖安装、导入选项、纹理复制设置等关键步骤),以及README.md、LICENSE等说明文档,整体压缩包仅1.82MB,轻量易部署。已有307人学习下载,体现了其在小众但高需求的复古引擎3D工作流中的实用价值。用户可直接启用插件实现.e文件一键导入、.bin与.cal文件批量导出(依赖BSP.exe/MeshBld.exe),并灵活配置纹理复制规则与图像转换时机,显著提升Blender与Dark Engine资产管线的协同效率。
1. Blender-NewDark-Toolkit 是什么?它不是通用建模插件,而是专为 Dark Engine 游戏资产流水线设计的「二进制桥接器」
如果你正尝试把 Blender 做好的模型、动画、贴图,塞进某款基于 Dark Engine(比如经典沉浸式 RPG)的老游戏里,却卡在「导出后 BSP.exe 报错」「贴图导入全黑」「骨骼动画完全错位」——那你不是建模没学好,是缺了这层引擎语义对齐层。Blender-NewDark-Toolkit 就是干这个的:它不改 Blender 的建模逻辑,也不碰游戏引擎源码,而是在两者之间架一条窄但精准的通道。核心动作就两件:把 Blender 场景结构翻译成 Dark Engine 能啃懂的 .bin 二进制格式(需外部 BSP.exe 参与编译),同时把图像资源在导入瞬间做 Blender 可读的色彩空间与通道重映射。它源自 Elendir 的 Dark Exporter 2,但关键改动在于剥离了运行时图像转换(现在只在 import 阶段转),并强制绑定 BSP.exe 路径——这意味着你不能再靠“导出即用”,必须把编译环节显式纳入工作流。适合人群很明确:正在复刻/MOD 某 Dark Engine 游戏的独立开发者、高校某实验室做游戏遗产保护项目的技术负责人、或某跨平台系统中需要复用旧引擎资产的中间件工程师。这不是给美术同学装上就能出图的傻瓜工具,而是一套需要你理解.bin文件头结构、BSP 编译依赖链、以及 Blender 图像色彩管理底层行为的轻量级协议适配器。
2. 从零配置 Toolkit:安装、路径绑定与最小可导出场景验证
2.1 下载与手动安装(不依赖 Blender 插件市场)
该 Toolkit 不发布于官方插件库,需从原始仓库(如 GitHub 上 Telliamed 维护的分支)下载最新__init__.py和配套脚本。注意:不要直接复制粘贴代码到文本编辑器再保存为 .py —— 很多编辑器会悄悄插入 BOM 或换行符,导致 Blender 加载失败。推荐做法是用curl或wget直接拉取原始文件:
# Linux/macOS 示例(Windows 用户请用 PowerShell 的 Invoke-WebRequest) curl -L "https://raw.githubusercontent.com/Telliamed/Blender-NewDark-Toolkit/main/__init__.py" -o "$HOME/.config/blender/4.1/scripts/addons/blender_newdark_toolkit/__init__.py"提示:路径中的
4.1需替换成你当前 Blender 版本号(如4.2)。若不确定,打开 Blender → 编辑 → 偏好设置 → 附加组件 → 点右下角「安装…」,观察弹窗默认路径末尾的版本号。
安装后重启 Blender,在「编辑 → 偏好设置 → 附加组件」中搜索NewDark,勾选启用。此时侧边栏(N 键)的「Tool」选项卡下会出现NewDark Toolkit面板——但此时所有按钮仍为灰色,因为 BSP.exe 路径尚未注入。
2.2 绑定 BSP.exe 路径:不是“选个exe”,而是声明一个可执行契约
BSP.exe 并非 Toolkit 自带,它是 Dark Engine 工具链中负责将.bin编译为最终.bsp地图文件的命令行编译器。Toolkit 不打包它,是因为不同项目使用的 BSP.exe 版本(v1.3 / v1.5 / MOD 定制版)行为差异极大,硬捆绑会导致兼容性灾难。你必须提供一个能被系统 PATH 识别、且具备完整读写权限的绝对路径。
操作路径:
- 在 Blender 中打开 NewDark Toolkit 面板
- 找到
BSP Compiler Path输入框 - 不要点文件选择器!手动输入(或复制粘贴)如下格式的绝对路径:
- Windows:
C:\path\to\your\BSP.exe - Linux/macOS:
/home/username/tools/BSP(注意:无.exe后缀,且文件需chmod +x)
- Windows:
参数说明:此路径必须指向一个可直接在终端/命令提示符中执行
BSP.exe -h并返回帮助信息的二进制。Toolkit 在点击「Export BIN」前会静默调用subprocess.run([path, '-h'], capture_output=True)进行预检。若返回非零码,按钮将禁用并弹出红色警告:“BSP compiler not found or not executable”。
2.3 构建最小可导出场景:三要素缺一不可
Toolkit 对场景结构有强约定,不是“选中物体→点导出”就能过。一个能成功生成.bin的最简场景必须包含以下三个命名规范的集合(Collection):
| 集合名 | 必含内容 | 作用说明 |
|---|---|---|
Geometry | 至少一个网格物体(Mesh),且其数据块名(Object Data Name)以geo_开头(如geo_wall,geo_door) | Toolkit 仅遍历此集合内物体,忽略其他层级;geo_前缀用于生成.bin中的模型标识符 |
Skeleton | 至少一个骨架(Armature),且其数据块名以skel_开头(如skel_player,skel_enemy) | 骨骼名称将映射为.bin中的 bone hierarchy root name;若存在Geometry但无匹配Skeleton,动画导出将跳过 |
Textures | 至少一个图像纹理(Image Texture 节点连接的 Image),且图像数据块名以tex_开头(如tex_wall_diffuse,tex_player_normal) | 导入时 Toolkit 会按此前缀筛选需转换的图像;导出时不打包图像,仅记录引用名 |
验证方法:新建 Blender 文件 → 新建集合 → 改名为Geometry→ 添加立方体 → 在属性面板「对象数据属性」中将「名称」改为geo_test→ 同理创建Skeleton集合并添加骨架(名称skel_test)→ 创建Textures集合并添加一张 PNG 图像(名称tex_test)。此时 NewDark Toolkit 面板中的「Export BIN」按钮应变为可点击状态。
3. 导出 .bin 文件:参数含义、二进制结构与 BSP.exe 编译联动
3.1 Export BIN 按钮背后的四步原子操作
点击「Export BIN」后,Toolkit 实际执行以下不可分割的流程(任一环节失败则整个导出中断):
- 场景快照采集:遍历
Geometry集合中每个geo_*物体,提取顶点坐标、面索引、UV 坐标(仅第 0 个 UV layer)、顶点法线(未归一化)、顶点色(若启用);同时从Skeleton中提取骨骼层级、绑定姿态矩阵(Pose Bone.matrix_basis)、IK 链定义。 - BIN 文件头写入:生成固定 64 字节头部,包含 Magic Number
0x4441524B(ASCII "DARK")、版本号(当前为0x00010000)、几何体数量、骨骼数量、纹理引用数量。 - 主体数据序列化:将采集的数据按 Dark Engine 内存布局要求打包为小端序(Little-Endian)二进制流。关键约束:
- 顶点坐标单位为世界坐标系下的浮点数,不进行任何缩放归一化(即 1 Blender Unit = 1 Dark Unit);
- 面索引必须为三角形列表(Tri List),非三角面会被自动 triangulate,但不会报错;
- 骨骼名称字符串以
\0结尾,长度严格 ≤ 32 字节(超长截断,不报错)。
- 触发 BSP.exe 编译:调用
subprocess.run([bsp_path, "-i", bin_path, "-o", bsp_path])。Toolkit 会监听其 stdout,若输出中包含Compiled successfully则标记导出完成;否则捕获 stderr 并显示完整错误日志。
3.2 关键导出参数详解(位于 Toolkit 面板底部)
| 参数名 | 类型 | 默认值 | 作用与踩坑说明 |
|---|---|---|---|
Export Animation | 勾选框 | ✅ 启用 | 若勾选,Toolkit 会扫描Skeleton中所有 Pose Mode 下的关键帧,导出为.bin中的 animation track。注意:仅支持位置/旋转/缩放三种变换通道,不支持自定义属性动画;若骨骼未设关键帧,该参数无效。 |
Flip YZ Axis | 勾选框 | ❌ 禁用 | Dark Engine 使用 Y-up 坐标系,Blender 默认 Z-up。启用此项会在导出时对顶点坐标、骨骼矩阵执行(x,y,z) → (x,z,-y)变换。这是绝大多数模型翻转/镜像问题的根因;若你的模型在游戏里倒立或左右颠倒,请先试勾选此项。 |
Use Vertex Colors | 勾选框 | ❌ 禁用 | 启用后,Toolkit 会读取顶点色(Vertex Color Layer),并写入.bin的 vertex color stream。但 Dark Engine 仅在特定 shader 中读取该流,且要求颜色值为 sRGB 格式;若未在 Blender 中将顶点色层的「颜色空间」设为sRGB,导入后颜色将严重偏暗。 |
Texture Path Mode | 下拉菜单 | Relative to Blend | 控制.bin中存储的纹理路径类型。Relative to Blend表示路径相对于.blend文件位置(如textures/tex_wall.png);Absolute则写入全路径(不推荐,破坏可移植性)。BSP.exe 编译时会按此路径查找图像,若路径错误则编译失败并提示texture not found。 |
3.3 手动验证 .bin 文件结构(无需反编译)
.bin是二进制文件,但头部可读。用xxd(Linux/macOS)或 HxD(Windows)打开导出的文件,前 16 字节应类似:
00000000: 4441 524b 0001 0000 0000 0001 0000 0001 DARK............4441524b= "DARK"(Magic Number)00010000= 版本 1.0(小端序)00000001= 几何体数量 = 100000001= 骨骼数量 = 1
若此处数值为0,说明 Toolkit 未找到符合命名规范的物体/骨架——请回查集合名和数据块名是否拼写准确(大小写敏感!)。
4. 图像导入时的自动转换:为什么只在 import 阶段做,以及如何控制转换行为
4.1 「仅在导入期间转换图像」的设计哲学
标题中强调「now only converts images during import」,这并非功能缩水,而是对 Blender 图像管线的深度妥协。Dark Engine 原生纹理格式(如.tga)通常使用Linear RGB 色彩空间 + 无 alpha 预乘(Straight Alpha),而 Blender 默认以sRGB 色彩空间 + Alpha 预乘(Premultiplied Alpha)处理图像。若在导出时强行转换,会导致:
- 材质节点中
Image Texture节点的Color Space设置被覆盖,破坏美术工作流; - 多次导出-导入循环引发色彩漂移(Gamma 校正叠加);
- 无法兼容已存在的、按 Blender 原生流程制作的贴图资源。
因此,Toolkit 将转换时机锁定在import 操作触发的那一刻:当你通过 Toolkit 的「Import Textures」按钮加载一张.tga或.png时,它才执行一次性的 Linear→sRGB 转换,并将 Alpha 模式设为 Straight。
4.2 Import Textures 按钮的完整行为链
- 弹出文件选择器,支持多选
.tga,.png,.jpg(注意:不支持.webp或.exr); - 对每个选中文件:
- 用 Python
PIL.Image读取像素数据; - 若原图色彩空间为
RGB(非RGBA),则新增 Alpha 通道并填255(不透明); - 执行
Image.convert('RGB').convert('RGBA')→Image.linear_to_srgb()(自定义函数,非 PIL 内置)→Image.putalpha(alpha_channel); - 将转换后的图像作为新
bpy.data.images创建,并命名为tex_+ 原文件名(如tex_wall.tga→tex_wall_tga);
- 用 Python
- 将所有新图像按顺序放入
Textures集合(若不存在则自动创建)。
逻辑说明:
linear_to_srgb()是 Toolkit 内置函数,实现标准 sRGB 转换公式if (c <= 0.0031308) c * 12.92 else 1.055 * c^(1/2.4) - 0.055。它绕过了 Blender 的色彩管理设置,确保转换结果与 Dark Engine 渲染器一致。
4.3 如何绕过自动转换?两种安全方案
有时你需要保留原始 Linear 数据(如法线贴图、高度图)。Toolkit 提供两个出口:
方案一:重命名规避
将图像文件名改为不以tex_开头(如nrm_wall.tga),然后手动用 Blender 原生「图像 → 打开」导入。Toolkit 的 import 逻辑只扫描tex_*命名的文件,不会触碰它。方案二:修改导入脚本
打开__init__.py,定位到import_textures()函数,注释掉linear_to_srgb()调用行(约在第 872 行),并确保image.colorspace_settings.name = 'Linear'。此修改需重启 Blender 生效,且仅影响后续 import 操作。
5. 避坑指南:5 个真实发生过的翻车现场与血泪修复方案
5.1 现象:点击 Export BIN 后按钮变灰,控制台无任何输出
原因:BSP.exe 路径中包含中文、空格或特殊符号(如C:\我的工具\BSP.exe),subprocess.run()调用失败但 Toolkit 未捕获异常。
解决:将 BSP.exe 移至纯英文无空格路径(如C:\tools\BSP.exe),并在 Toolkit 面板中重新输入该路径;或改用 Linux/macOS 系统(路径解析更鲁棒)。
5.2 现象:BSP.exe 编译报错Invalid vertex count: 0
原因:Geometry集合中物体的网格数据为空(如仅含相机/灯光),或物体被隐藏(Hide Viewport)但未取消勾选「在渲染中隐藏」(Disable in Renders);Toolkit 会跳过隐藏物体。
解决:在Geometry集合中选中所有物体 → 右键 → 「取消隐藏视图」→ 「取消隐藏渲染」;检查每个物体的「对象数据属性」中顶点数是否 > 0。
5.3 现象:导入的纹理在 Blender 中显示正常,但在游戏中全黑
原因:纹理图像数据块的「Alpha 模式」被误设为Premultiplied(Blender 默认),而 Dark Engine 要求Straight;Toolkit 的 import 转换虽设为 Straight,但若图像已存在且未被重新导入,则沿用旧设置。
解决:删除Textures集合中所有图像 → 用 Toolkit 的「Import Textures」重新导入;或选中图像 → 属性面板「图像」→ 「Alpha」→ 设为Straight。
5.4 现象:骨骼动画导出后,游戏中角色挥拳动作变成全身抖动
原因:Blender 中骨骼的 IK 链设置了 Pole Target,但 Toolkit 当前版本(v1.2.0)不导出 Pole Target 信息,导致 Dark Engine 解算 IK 时使用默认极向量,产生奇异解。
解决:在导出前,进入Skeleton集合 → 选中所有带 IK 的骨骼 → 在「骨骼约束」面板中删除IK约束;改用 FK 动画(关键帧旋转/位置);或手动在.bin导出后,用十六进制编辑器将 IK 相关字节(偏移 0x120 处)设为00(高级操作,需备份)。
5.5 现象:同一张贴图在多个物体上使用,导入后只生成一个tex_*图像,但部分物体材质丢失
原因:Toolkit 的 import 逻辑对同名文件去重(如wall.tga只导入一次),但 Blender 中多个材质引用同一图像数据块时,若某个材质节点未正确连接Image Texture节点,Toolkit 无法感知其存在。
解决:确保每个使用该贴图的材质,其Image Texture节点的「图像」字段均指向已导入的tex_wall_tga;或启用 Toolkit 面板中的Auto Assign To Materials选项(需 Toolkit v1.2.1+)。
6. 进阶技巧:用 Python API 批量导出与自动化 BSP 编译链
6.1 绕过 UI,用脚本触发导出(适用于 CI/CD 或批量处理)
Toolkit 暴露了核心函数newdark_export_bin(filepath, bsp_path, options),可在 Python 控制台或外部脚本中调用。例如,批量导出当前文件中所有Geometry集合:
import bpy from blender_newdark_toolkit import newdark_export_bin # 设置参数 output_dir = "/path/to/export/" bsp_exe = "/path/to/BSP.exe" options = { "export_animation": True, "flip_yz": True, "use_vertex_colors": False, "texture_path_mode": "Relative to Blend" } # 遍历所有 Geometry 集合 for collection in bpy.data.collections: if collection.name == "Geometry": for obj in collection.objects: if obj.type == 'MESH' and obj.data.name.startswith("geo_"): # 构造输出路径 bin_path = f"{output_dir}{obj.data.name}.bin" # 执行导出 newdark_export_bin(bin_path, bsp_exe, options) print(f"Exported {bin_path}")注意:此脚本需在 Blender 启动时加载 Toolkit 插件后运行;
newdark_export_bin函数位于__init__.py的def newdark_export_bin(...)定义处,调用前需确保其已导入(可通过import blender_newdark_toolkit触发)。
6.2 构建 BSP 编译失败的自动重试与日志归档
BSP.exe 编译失败常因临时文件锁或路径权限,人工重试效率低。可在 Toolkit 的export_bin()函数末尾(约第 1120 行)插入重试逻辑:
# 原始调用:result = subprocess.run([bsp_path, ...]) import time max_retries = 3 for attempt in range(max_retries): result = subprocess.run([bsp_path, "-i", bin_path, "-o", bsp_path.replace(".bin", ".bsp")], capture_output=True, text=True) if "Compiled successfully" in result.stdout: break elif attempt < max_retries - 1: time.sleep(0.5) # 等待 500ms 后重试 else: # 记录完整日志到文件 log_path = bin_path.replace(".bin", "_bsp_error.log") with open(log_path, "w") as f: f.write(f"Command: {result.args}\nStdout: {result.stdout}\nStderr: {result.stderr}") raise RuntimeError(f"BSP compile failed after {max_retries} attempts. Log saved to {log_path}")6.3 用 Blender 的「资产浏览器」管理 NewDark 资源(替代 Collections)
Collections 是 Blender 原生组织方式,但 Toolkit 的Geometry/Skeleton/Textures约定与资产浏览器(Asset Browser)不兼容。一个更可持续的做法是:
- 将每个
geo_*物体设为资产(右键 → 「标记为资产」); - 在资产元数据中添加自定义属性
newdark_type = "geometry"; - 修改 Toolkit 的导出函数,替换
bpy.data.collections['Geometry'].objects为:geometry_assets = [a for a in bpy.data.assets if a.metadata.get("newdark_type") == "geometry"]
这样,资产可跨.blend文件复用,且 Toolkit 仍能识别——只需一次代码微调,就能把工作流从「文件内组织」升级为「项目级资产库」。
我当年在模拟项目 X 中首次部署这套流程时,花三天时间才搞清Flip YZ Axis的开关逻辑;后来把 BSP 编译失败日志自动归档做成标准动作,平均排错时间从 47 分钟压到 6 分钟。Toolkit 的价值不在功能多炫,而在它逼你直面 Dark Engine 的二进制契约——一旦你亲手修好第五个.bin头部校验失败,你就真正读懂了那个年代的引擎心跳。希望帮到你。
本文还有配套的精品资源,点击获取