Origin
zhuanlan.zhihu.com
Tags
程序化
Houdini
开放世界
技术详解
经验分享
项目
收藏夹
创建时间
收藏类型
Cubox 深度链接
更新时间
原链接
描述
由于地形精度问题及基于高度图的限制,山体(就是那个包子)侧面结构纯靠地形系统无法表现,需要用 mesh 进行装饰。对于大世界场景而言,由于此类区域面积巨大,以及地形不断迭代变更,手工制作和维护悬崖过于耗时,希望走程序化生成路线。
下面讨论几种悬崖(cliff)生成方法:
一,过程化建模方法
farcry5 的悬崖生成方法最广为人知,它先提取山体侧面,然后进行切割、置换等操作产生悬崖模型,走的是过程化建模的路子:
notion image
notion image
对于特定类型的悬崖(分层形态的),效果是很不错的。缺点是:1,需要的面数较高。2,算法决定风格。
二,堆砌方法
最开始是在刺客信条的分享上看到的,但不确定是自动的还是手工的:
notion image
后来在另一个分享中看到的一个自动的:
是 看门狗 2 中用的方法:
notion image
notion image
这种堆砌方法的好处是可以走 gpu instancing,缺点仍然是算法决定风格。
三,美术导向方法(第一次尝试:置换方法)
我们希望寻找一种可定制性更强的方法。让美术能够更灵活地定制风格。
最简单的想法是让美术自己去找一张悬崖的置换图(displacement map)输入给 houdini,houdini 用它对山体侧面进行置换。过程如下:
(1),将山体侧面提取出来,然后按四方向进行分片,使各片(后面称为 patch)上三角面朝向差异不致于过大。
(2),对 patch 进行细分。
(3),将悬崖置换图贴上去,进行 displacement。
置换图:
notion image
结果如下:
notion image
可见,由于面数限制,远看 ok,近看很多锯齿和纹理拉伸,是无法接受的。
究其原因,是因为此种置换方法没有 “将面数用在刀刃上”,布线也不是“跟着结构走” 的。因此我想到下面的贴片方法。
四,美术导向方法(第二次尝试:贴片方法)
不再用置换图,而是让美术建一个对应的低模贴片(模板 tile,四方连续),由于是手工建模,故可做到布线跟着结构走(仅将转折处用布线卡出来,而无转折处不浪费布线),这样贴片的面数就比较低:
notion image
然后将贴片 “贴” 到山体侧面上。如果山体侧面是曲面,则我们也会对贴片进行弯曲。方法如下:
(1),将山体侧面提取出来,然后按四方向进行分片,使各片(后面称为 patch)上三角面朝向差异不致于过大。
(2),将 patch 各顶点的 P 存储到 P2,然后把 patch 转到 uv 空间 patch_uvspace。
(3),将 tile 各点的高度值 P.y 存储到 Y,然后把 tile 也转到 uv 空间 tile_uvspace。
(4),将 tile_uvspace 无缝平铺为 ground_uvspace。
(5),将 ground_uvspace 中与 patch_uvspace 没有对应的部分删除,得到 ground_uvspace_cut。
(6),对 ground_uvspace_cut 每个顶点,找到 patch_uvspace 上的对应位置,通过插值获得 P2 属性值。
(7),对 ground_uvspace_cut 各顶点执行 P=P2 转回世界空间,得到 ground_worldspace。
此时 ground_worldspace 已经贴到 patch 的位置了,只是还没有凹凸。
(8),对 ground_worldspace 各顶点沿法线偏移 Y 产生凹凸,得到 ground_worldspace_displace。
(9),然后再对 ground_worldspace_displace 边缘做一些处理,使边缘贴合山体即得最终 cliff mesh。
我对此算法进行了一个鲁棒性测试,就是去年(2020)发过的这个视频:
可见,即使对于猪头这种比较复杂的模型,也能较好地贴上去。
将其用于实际场景,流程如下:
notion image
效果:
notion image
五,总结
上面讨论了 过程化建模、堆砌、置换、贴片 几种悬崖生成方法。
其中过程化建模方法对于风格的可定制性是最差(只能定制贴图),算法与效果之间一个萝卜一个坑,很难做到通用。所以我一直强调如下观点:做程序化生成,要尽量 “我们不生成美术资源,只做美术资源的装配工”,过程化建模的路子则与此相背。
置换和贴片两种方法是我希望实现风格灵活定制而做的尝试,贴片方法是置换方法的改进,解决了置换方法对面数要求过高(否则产生瑕疵)的问题。是一个有趣且切实可行的方案。但对于很大的场景,生成的悬崖 mesh 仍然会比较大(过程化建模方法亦存在同样问题),需要切块 streaming。
堆砌方法在风格的可定制性上也有一些局限,但比过程化建模方法要强,至少石块是可定制的。而堆砌法最大的优势是资源重用和 gpu instancing,包体和渲染性能都更好。基于这个原因,我其实现在更倾向于堆砌法。后面打算抽空研究下如何 “堆得好看”,这应该和算法及资源选取都有关系。另外,想到 UE5 里可以无限堆量这点,我觉得堆砌法更有前途了:D
—- 补充 > 本文由简悦 SimpRead 转码