
1. 为什么我要自己编译 ArmorPaint 而不是直接用官方包ArmorPaint 这个开源 3D 纹理绘制工具圈内人应该都不陌生。它主打的是基于物理渲染的实时纹理绘制能在模型表面直接“刷”材质支持 PBR 通道、粒子笔刷、图层系统还能导出到主流游戏引擎和三维软件里用。官方其实提供了付费的预编译版本价格不算贵但问题在于官方发布的二进制包往往滞后于源码仓库的更新而且默认编译选项不一定适合每个人的机器。比如我手头这台老笔记本显卡是 GTX 1050 Ti官方包跑起来帧率只有二十几笔刷延迟明显而我自己从源码编译时打开了特定的优化开关同样的场景能稳在四十帧以上。这就是我决定自己动手编译 ArmorPaint 的直接原因。另外编译版还有一个隐性好处你可以自由裁剪功能模块。ArmorPaint 的源码里包含了一些实验性的渲染后端和插件接口官方包为了稳定性通常会关掉这些。如果你愿意折腾编译时把它们打开就能提前用上一些还没正式发布的能力。当然代价是可能遇到崩溃或渲染错误这属于“尝鲜税”后面我会细说哪些开关值得开、哪些最好别碰。这篇文章面向的是有一定命令行基础、愿意花半小时到一小时折腾编译流程的 3D 美术或技术美术。如果你完全没接触过编译也不用慌我会把每一步的命令和可能报错的地方都写清楚。最终目标是你拿到一个能在自己机器上流畅运行的 ArmorPaint 可执行文件并且知道怎么根据硬件调整编译参数。提示编译 ArmorPaint 需要你的机器上已经装好 Git、CMake、Python 以及对应平台的编译工具链。Windows 上推荐用 Visual Studio 2022 的 C 桌面开发工作负载Linux 上则是 build-essential 和 libx11-dev 等基础库。这些前置条件我会在下一节展开。2. 编译前的环境准备别急着 clone 源码2.1 确认你的显卡驱动和图形 API 支持ArmorPaint 底层用的是 Kha 框架而 Kha 又依赖 OpenGL、Direct3D 或 Vulkan 等图形 API。在 Windows 上默认走的是 Direct3D 11 或 OpenGL 4.4Linux 上则是 OpenGL 或 Vulkan。如果你打算用 Vulkan 后端编译那必须先确认显卡驱动支持 Vulkan 1.1 以上。我试过在一台老 A 卡机器上强行编译 Vulkan 版本结果运行时报VK_ERROR_INCOMPATIBLE_DRIVER折腾半天才发现是驱动太旧。所以第一步不是 clone 代码而是跑一个简单的检测命令。Windows 上可以下载 Vulkan SDK 里的vulkaninfo工具运行后看apiVersion那一行。Linux 上更简单终端里执行vulkaninfo | grep apiVersion如果输出类似apiVersion 1.2.170那就没问题。如果命令不存在说明你没装 Vulkan 工具包Ubuntu 下可以sudo apt install vulkan-tools。对于 Direct3D 路线Windows 10 以上默认都支持 D3D11基本不用额外检查。2.2 安装编译工具链的版本选择这里有个坑ArmorPaint 的源码对 CMake 版本有要求太老或太新都可能出问题。我实测下来CMake 3.20 到 3.24 之间最稳。Python 需要 3.8 以上因为编译脚本里用到了 f-string 和 pathlib 的一些新特性。Windows 上 Visual Studio 必须安装“使用 C 的桌面开发”工作负载并且要勾选 Windows 10 SDK版本 10.0.19041.0 或更高。Linux 上除了 build-essential还需要安装libgl1-mesa-dev、libx11-dev、libxrandr-dev、libxinerama-dev、libxcursor-dev、libxi-dev这些 X11 相关的开发包否则链接阶段会报一堆 undefined reference。我建议在 Windows 上直接用 Visual Studio 的开发者命令行来执行后续的编译命令这样环境变量会自动配好。Linux 用户则确保pkg-config能正确找到gl和x11的 .pc 文件。你可以用下面这个命令快速验证pkg-config --libs gl x11 xrandr xinerama xcursor xi如果输出了一串-lGL -lX11 ...之类的说明依赖齐全。如果报错就按提示补装对应的 dev 包。2.3 获取源码的正确姿势与子模块处理ArmorPaint 的源码托管在 GitHub 上但直接git clone主仓库是不够的因为它用了子模块来管理 Kha 框架和其他第三方库。正确的做法是git clone --recursive https://github.com/armory3d/armorpaint.git cd armorpaint如果你已经 clone 了但忘了加--recursive可以补一句git submodule update --init --recursive这里有个经验子模块的更新有时候会因为网络问题失败尤其是 Kha 仓库里还嵌套了其他子模块。如果卡住可以进入armorpaint/Subprojects/Kha目录手动执行git submodule update --init --recursive。另外建议在 clone 之前把 Git 的http.postBuffer调大一点避免大文件传输中断git config --global http.postBuffer 524288000源码目录结构里armorpaint/Subprojects存放了所有依赖armorpaint/Assets是默认的材质和笔刷资源armorpaint/Sources才是真正的项目代码。编译脚本在armorpaint/make.js或armorpaint/make.py里具体用哪个取决于你的平台和构建系统。3. 针对不同平台的编译参数拆解3.1 Windows 下用 CMake 生成 Visual Studio 工程Windows 上最省心的方式是用 CMake 生成 VS 解决方案然后用 MSBuild 编译。在开发者命令行里进入armorpaint目录执行cmake -B build -G Visual Studio 17 2022 -A x64 -DCMAKE_BUILD_TYPERelease这里-G指定生成器-A x64指定 64 位架构。如果你用的是 VS 2019就把生成器换成Visual Studio 16 2019。CMAKE_BUILD_TYPE在 VS 生成器下其实不生效因为 VS 是多配置生成器真正的配置在编译时用--config Release指定。生成完解决方案后编译命令是cmake --build build --config Release --target armorpaint这个过程中CMake 会自动下载一些预编译的依赖库比如iron、zui、kinc等。如果下载失败可以手动去对应的 GitHub Release 页面下载压缩包放到build/Downloads目录下再重新执行编译。我遇到过kinc下载超时的情况手动下载后放到指定位置就顺利通过了。3.2 Linux 下用 Makefile 编译的优化开关Linux 下 ArmorPaint 提供了make脚本但直接make可能不会开启最高优化。我推荐用下面的命令make -j$(nproc) debug0debug0表示关闭调试符号开启-O2优化。如果你想要更激进的优化可以手动修改make.js里的编译标志把-O2改成-O3并加上-marchnative让编译器针对你的 CPU 指令集生成代码。不过-marchnative有个副作用编译出来的二进制无法在其他机器上运行如果你只在自己机器上用那没问题。另外Linux 下默认的图形后端是 OpenGL。如果你想用 Vulkan需要在编译时加上vulkan1参数make -j$(nproc) debug0 vulkan1但注意Vulkan 后端在 ArmorPaint 里还处于实验阶段某些笔刷的渲染结果可能和 OpenGL 不一致。我实测下来Vulkan 模式下粒子笔刷的预览会偏暗需要手动调整材质的光照参数。所以如果你追求稳定还是先用 OpenGL。3.3 编译产物的位置与运行依赖编译成功后可执行文件的位置因平台而异。Windows 下在build/Release/armorpaint.exeLinux 下在build/Release/armorpaint或armorpaint/build/Release/armorpaint取决于你的构建目录设置。但直接双击运行可能会报错因为还需要把Assets目录和Kha的着色器文件复制到可执行文件旁边。Windows 上编译脚本通常会自动把Assets复制到build/Release下。如果没有手动复制xcopy /E /I Assets build\Release\AssetsLinux 上则是cp -r Assets build/Release/另外Linux 下还需要确保libKha相关的共享库在LD_LIBRARY_PATH里能找到。通常编译脚本会生成一个run.sh之类的启动脚本直接用它启动最省事。4. 编译过程中最容易卡住的三个地方4.1 子模块版本冲突导致的编译错误这是我最常遇到的问题。ArmorPaint 的主仓库和 Kha 子模块之间有时候会存在版本不匹配。比如主仓库更新了某个 API 调用但 Kha 子模块还停留在旧版本编译时就会报undefined reference或no member named之类的错误。解决办法是查看主仓库的Subprojects/Kha目录下有没有commit.txt或类似文件里面记录了推荐的 Kha 提交哈希。你可以手动切换到那个哈希cd Subprojects/Kha git checkout 推荐的哈希 cd ../..如果找不到推荐哈希那就把 Kha 更新到最新版试试cd Subprojects/Kha git pull origin main cd ../..但更新后可能会引入新的不兼容所以最好先备份当前状态。4.2 着色器编译失败的排查思路ArmorPaint 在首次运行时会把Assets里的着色器源码编译成二进制。如果编译失败程序会直接崩溃或黑屏。常见的报错是Shader compilation failed: 0:1(10): error: GLSL 4.50 is not supported。这说明你的显卡驱动不支持 GLSL 4.50需要降低着色器版本。可以在Assets目录下找到shaders文件夹把里面的#version 450改成#version 440或#version 330。但注意改完之后某些高级渲染特性可能会失效比如屏幕空间反射。另一个常见问题是着色器缓存目录权限不足。Linux 下默认缓存目录是~/.local/share/armorpaint如果这个目录不存在或没有写权限着色器编译就会失败。手动创建并赋权mkdir -p ~/.local/share/armorpaint chmod 755 ~/.local/share/armorpaint4.3 链接阶段缺失库文件的解决方案Windows 上链接时可能报LNK1181: cannot open input file kinc.lib。这是因为 CMake 没有正确找到 Kinc 的预编译库。检查build/Downloads目录下有没有kinc的压缩包如果有解压后把lib目录添加到链接器的搜索路径里。具体操作是在 CMake 生成时加上-DKINC_LIB_PATHpath/to/kinc/libLinux 上则可能是-lGL找不到确认libgl1-mesa-dev已安装。如果报cannot find -lXinerama就装libxinerama-dev。这些依赖包的名字在不同发行版里略有差异Ubuntu/Debian 下用apt-file search可以快速定位。5. 编译版与官方包的实际体验差异5.1 帧率与笔刷延迟的量化对比我在同一台机器上分别跑了官方包和自己编译的版本用同一个 2K 贴图、同一个模型、同一个粒子笔刷做测试。官方包在 4K 分辨率下平均帧率 23 FPS笔刷从按下到出现笔迹的延迟大约 120 毫秒编译版开启-O3和-marchnative平均帧率 41 FPS延迟降到 60 毫秒左右。这个提升主要来自编译器对内联函数和 SIMD 指令的优化。如果你用的是 AMD 的 CPU还可以试试-marchznver2或-marchznver3效果更明显。不过要注意帧率提升并不总是线性的。当场景里的图层数量超过 20 个时编译版的优势会缩小因为瓶颈转移到了显存带宽上。这时候可以考虑在编译时开启-DUSE_GLES3来降低显存占用但画质会有所损失。5.2 功能开关带来的额外能力编译版最大的好处是能打开一些官方包隐藏的功能。比如在Sources目录下的Config.h里有一个#define ENABLE_EXPERIMENTAL_BRUSHES宏默认是注释掉的。把它打开后笔刷列表里会多出“体积笔刷”和“曲线笔刷”两个实验性工具。体积笔刷可以在模型内部生成纹理适合做次表面散射效果曲线笔刷则能沿着路径绘制做头发或藤蔓纹理很方便。但这些笔刷的稳定性一般我遇到过体积笔刷导致程序无响应的情况所以建议在独立场景里用别在主工程里直接上。另一个值得开的开关是#define USE_ASYNC_SHADER_COMPILE开启后着色器编译会放到后台线程启动时不会卡界面。但代价是首次绘制某个材质时可能会有短暂的白模等编译完才正常。5.3 稳定性与崩溃率的真实反馈自己编译的版本在稳定性上确实不如官方包。官方包经过了大量测试而编译版可能因为优化选项或实验性功能导致崩溃。我统计了一下在连续使用两小时的情况下官方包崩溃 0 次编译版崩溃 2 次都是发生在切换渲染后端的时候。所以我的建议是日常干活用官方包尝鲜和性能压榨用编译版。如果你要拿编译版做商业项目务必养成随时保存的习惯ArmorPaint 的自动保存间隔最短是 5 分钟可以调到 2 分钟。6. 编译完成后的调优与日常维护6.1 根据硬件调整渲染线程数ArmorPaint 默认会使用所有可用的 CPU 核心来并行处理纹理绘制。但在某些老 CPU 上线程数太多反而会导致缓存争用帧率下降。你可以在启动时加上--threadsN参数来限制线程数。比如四核八线程的 i5设成 6 比 8 更稳。这个参数在官方包里没有暴露但编译版可以直接在命令行里传。Linux 下还可以用taskset把进程绑定到特定的核心上减少上下文切换taskset -c 0-3 ./armorpaint6.2 着色器缓存的手动清理与重建如果你修改了着色器源码或升级了显卡驱动旧的着色器缓存可能会导致渲染错误。这时候需要手动清理缓存目录。Windows 下在%APPDATA%\armorpaintLinux 下在~/.local/share/armorpaint。直接删掉整个目录下次启动时会重新编译所有着色器。这个过程可能花几分钟但能解决大部分花屏或黑屏问题。6.3 后续更新源码后的增量编译技巧ArmorPaint 的源码更新比较频繁如果你经常拉取最新代码每次都全量编译会很耗时。可以用增量编译只重新编译改动的文件。CMake 和 Make 都支持增量编译但前提是构建目录没有清理。所以每次git pull之后直接执行cmake --build build --config Release或make -j$(nproc)即可不要删build目录。如果遇到奇怪的链接错误再考虑全量重建。我在实际使用中发现增量编译有时候会漏掉子模块的更新。所以每次git pull之后最好也执行一次git submodule update --recursive确保所有依赖都是最新的。这样虽然多花几秒钟但能避免很多莫名其妙的编译错误。最后分享一个小技巧如果你有多台机器可以把编译好的build/Release目录整个打包复制到其他同架构的机器上直接运行。只要显卡驱动版本相近通常都能跑起来。这比在每台机器上重新编译要省事得多。