本帖使用社区开源推广,符合推广要求。我申明并遵循社区要求的以下内容:
- 我的帖子已经打上 开源推广 标签: 是
- 我的开源项目完整开源,无未开源部分: 是
- 我的开源项目已链接认可 LINUX DO 社区: 是
- 我帖子内的项目介绍,AI生成、润色内容部分已截图发出: 是
- 以上选择我承诺是永久有效的,接受社区和佬友监督: 是
以下为项目介绍正文内容,AI生成、润色内容已使用截图方式发出
仓库地址:GitHub - PaiPai121/OccamForge · GitHub
(系统反馈github项目要用开源推广,不过我感觉这个东西还远没到能推广给大家用的程度,希望各位给点建议,板砖轻拍)
Background
大概是最近没什么意思,想弄 Blender 搞个犀牛坦克和灰熊坦克的模型,导入到天际线里面看刁民们开坦克上班。
同时又琢磨要不要顺便 3D 打印一个玩,就倒角、突起、格栅啥的该做做。反正我水平也一般,很快糊出来一坨屎。
这个面数直接爆炸。导入天际线的车辆资产,面数怎么着也应该是千级的吧,可是这个时候我却发现我这坨屎直接 60000 面。
我替大伙尝试过了,这个面数直接导入不进去,60000、45000、35000 都不行,30000 以下才勉强行。但是你一辆车就 30000 个面是不是太过分了?那么多刁民一掏口袋坦克,电脑岂不是冒烟?
但是我又不想手动重新建模(虽然说让我重新做个简单盒子,估计早就做完了),于是就想能不能利用 AI 做一个自动减面的工具?而且减面完了自动烘焙贴图,然后导入到城市天际线中去。
和 AI 大概聊了一下,目前大概有三种路线:
路线 1:人工 Retopo
这是 AAA 游戏的常规做法:
高模
↓
美术重建低模
↓
Bake
路线 2:Simplygon 路线
核心思想:
- 识别特征
- 保留轮廓
- 删除细节
本质上还是:
QEM + Feature Preservation
路线 3:现代研究路线
近几年开始出现一些新的方向,例如:
- Feature Aware QEM
- Mesh Simplification in the Wild
核心思想:
- 保留边界
- 保留高曲率区域
- 保留法线变化大的区域
优先压缩:
- 平面
- 重复细节
人工的方法肯定是不考虑的,我也不是拿去做商业模型,没有那么高的精度要求。当时觉得我的模型都是比较简单方正的,也许简单的路线 2 就可以 work。删一删特别小的面,合并合并,可能面数一下子就降低了。
V1 Rule-Based Optimizer
于是说干就干,立刻让 Codex 开始操刀。
Preprocess
最初先进行一次低风险的清理:
- 对共面或近似共面的多余三角做 Limited Dissolve
这一步不会大幅改变形状,是比较安全的默认开启项,但是效果一般。在 `rhino_tank` 上:
- `62,656 → 60,310 tris`
- 减少 `2,346 tris`
- 约 `3.74%`

可以说,离我们的目标还有很远,于是就需要进一步处理。所以这里理所当然地想到构建一个 pipeline,由保守到激进,看哪一步能够达到目标面数就停止。
Geometry Report and Conservative Candidate-Aware Reduce
在刚才的安全减面后,就得考虑哪里可以删面了。预处理后会先出一个 report,判断哪里适合优化:
- 平面区域
- 高密度区域
- 曲率区域
- silhouette 外轮廓贡献
- 可减面候选
- 应保护区域
- 可疑区域
再把这些面大概分成:
- `MUST_KEEP`
- `SOFT_KEEP`
- `REDUCE_FIRST`
- `DELETE_CANDIDATE`
然后进行预处理后的第一次减面:
- 使用 Geometry Report 的候选区域
- 保护 silhouette 和高重要结构
- 优先处理安全区域
- 不强行达标

效果嘛,肯定还是有效果,但是仍然达不到我们的目标。很多小纹理其实已经不需要保留,但是判断不出来,面数还是过多。那就需要更加激进的策略了。
Aggressive Reduce
最开始直接让它自由减面,坦克直接不成样子,图我也没留,就不提了。
后来和 Codex 讨论,就加了更详细的规则:
2A Structural Protection Expansion
不只保护 silhouette 命中的三角,还会扩张一圈邻接区域,避免只保护几百个点导致结构塌陷。
2B Detail Candidate Detection
标记低可见性小细节、细碎装饰、可删除或可强压缩区域。
2C Bucket-Based Controlled Decimate
按 bucket 分强度减面:
- `MUST_KEEP` 基本不动
- `SOFT_KEEP` 中等减
- `REDUCE_FIRST` 强减
- `DELETE_CANDIDATE` 极强减或清理
2D Local Fallback
如果还高于目标,继续优先压低重要区域;最后才考虑更危险的压缩。
Stage 2 的目标是:主体、炮塔、炮管、车体大轮廓先保住,再牺牲细节。

Detail Suppression
效果不够,自然还需要继续改,于是又有了新的一步。它的定位不是大范围 decimate,而是专门处理:
- 小钉子
- 小倒角
- 局部纹理
- 圆环
- 细长条带
- 重复高密度小特征
目前主要通过通用几何规则识别低重要细节,然后用更强的 Limited Dissolve / 局部清理处理。它已经让形状更稳定,但还有提升空间,尤其是更精准识别环状、条带状、重复细节。

效果嘛,只能说到这一步为止,多少有的用,但是离目标还远得很,该清除的细节还是没有清除。
导入游戏测试
不过做都做了,导入游戏试试看!

不过导入的时候我发现了一个傻 der 的事情。在渲染热力图的时候,AI 实现的方案是把响应位置替换成目标颜色的材质,然后它就清空了。

于是原本直接 build 烘焙的模型自带的贴图有颜色,它 optimize 以后反而成素体了!!!!!不行,给我改。

fine,导出和烘焙是没问题的,还是想搞好这个自动减面。
感兴趣的话可以看一下:OccamForge v1.0.0。
V2 cost simplifier
但是吧,这样也不是一个办法,细小的纹理识别还是很差。再让 AI 搞下去,它就要针对坦克的样式去硬编码地写 if else 了。
目前的方案如果再继续去做 stage 4、stage 5、stage 6,就会变得像 if else 堆起来的 rule-based 自动驾驶规控系统,庞大却又永远有解不完的问题。毕竟我当规控工程师这么久了我能不知道么。
于是让 AI 大概搜了一些现行方案。这里不过多赘述了,总之就是去用各种cost指标去评估哪些边可以塌陷,哪些不可塌陷。如果有感兴趣的朋友可以看 AssetForge 自动减面记 V2:和 Edge Cost 继续较劲 - KK空间
调研了一下QEM相关的内容,并让ai根据计算规则大哥绘制了一下

不过这里立刻就能发现一个问题,我们的需求是什么,这个 cost 又是在做什么?
举个例子,如果我们是一个大正方体,其中有一个面上有一个小尖尖,那么按照这个 cost 的设计,这个尖尖的 cost 应该会比大正方体的 cost 要高,但是这显然不合理。因为我们的需求是希望这个尖尖作为一个不重要的特征被清除掉。
用 AI 大哥总结的话讲,我们真正想保留的是 Silhouette 而不是 Curvature。
比如说轮毂细节:
虽然几何重要,但是视觉不重要
最终拍下的cost思路大概是
vertex importance / face evidence / scale signal
↓
project / aggregate onto edges
↓
final edge collapse cost
比如:
C_{final}(e=(u,v)) =
C_{QEM}(e)
\cdot W_{importance}(e)
+ P_{boundary}(e)
+ P_{sharp}(e)
其中:
W_{importance}(e) =
f(\max(I(u), I(v)), \max(S(u), S(v)))
这里大概画了几种cost (SVG文件好像显示的不太正常啊)


以及组合起来的score

(不过和AI大哥讨论的时候,大哥总是说这个不应该叫cost,还是叫score更合适)
Local simplification executor
有了cost分布,接下来就算需要把前面 heatmap diagnostics 和 combo score 产生的“哪里可以删”的判断,真正变成一个可执行的 edge-collapse 减面流程。
这个就不细说了,想了解的朋友也可以看这个博客链接
v2版本效果


(这个版本最开始还有贴图bug,不过现在修了)
OccamForge v2.0.1 release
当前版本的话就是面是减下来了,但是还是达不到理想的目标,不知道佬们还有没有什么建议