探索前沿 AI 应用边界
项目实作图形学与交互艺术

AI 程序化建模 让一朵花从网页开进 Unreal

用同一套数学规则生成模型,让花朵随着进度连续开放

在“双生共鸣”的设计中,两位参与者通过配合,让场地中央的一朵花逐渐开放。为了让花苞、半开和盛放之间都有自然的过渡,我们借助 AI,把花瓣的形状和开合过程写成可计算的规则:先在浏览器里调整形体,再生成三维网格,最后把同一套规则带进 Unreal,驱动实时动画。

约 8 分钟阅读 · 1 分 18 秒过程短片 · 双生共鸣项目
双生共鸣场景中的盛放花朵,青紫色花瓣位于双人站位之间
Unreal 场景中的盛放预览。主花由程序生成;森林背景、角色及其他场景素材沿用工程已有资源。画面展示的是美术预览状态。

从生成到调整,看看这朵花如何成形

从 AI 生成过程录屏中,选取花形、开合与光流的几次变化。

视频未能加载。请直接打开或下载视频。

1 分 18 秒 · 录屏选段以 2 倍速呈现,原素材无音轨,以画面说明引导观看。素材记录的是阶段性生成与修改画面,选段之间有剪切,并非一次连续的实时开合演示。

在蘑菇云案例中,我们尝试让 AI 把复杂形态拆成数学规则,做成可以交互、可以导出模型的网页。这一次,问题又往前走了一步:网页里生成的形体,能不能进入游戏引擎,继续随着一个参数变化?

“双生共鸣花”提供了一个具体的尝试。它需要停在任意开放程度,也需要让花脉跟着花瓣一起弯曲。只做好一张盛放画面还不够,模型必须有完整的中间状态。AI 在这里参与的是几何生成、网页预览和材质代码的编写,最终效果仍要回到程序与场景中检查。

先把花开变成一个可以调节的数

我们先为开合程度定义一个数,记作 Bloom,范围从 0 到 1。0 对应收拢的花苞,0.5 是半开,1 是盛放。接下来的工作,就是描述这个数改变时,花瓣上的每个点应该移动到哪里。

可以把一片花瓣想成一张可弯曲的纸:沿长度找到一个位置,再沿宽度找到一个位置,数学函数就能算出这个点的空间坐标。把许多采样点连成三角面,花瓣的表面就出现了。

这朵花共有四层,片数分别为 13、13、8、8,总共 42 片。同层花瓣围绕中心排布,相邻层稍微错开。程序又给各层设置不同的展开进度,让它们依次舒展,同时改变半径、宽度和弧度。

这些数字是为当前造型调整的美术参数。改变花瓣长度、层间错位或末端弯曲,就可以得到不同的花形;每次调整后,仍要检查轮廓是否合适、层与层之间是否穿插。

Unreal 场景中花瓣收拢的花苞状态
Bloom = 0,花瓣向中心收拢。
Unreal 场景中四层花瓣逐步展开的半开状态
Bloom = 0.5,各层花瓣处于不同的展开程度。与本文开头的盛放画面对照,可以观察同一套网格的形态变化。

让花脉跟着花瓣一起生长

有了主要轮廓,还需要能经得起近看的一些细节。我们把主花拆成花瓣、花脉、花心和根须四部分,让它们分别承担形体、线条、视觉中心和支撑结构的作用。

花脉的处理尤其关键。主脉沿花瓣中线延伸,侧脉向两边分叉,再继续分出更细的枝脉。每一级都沿用相似的规则,最多递归分叉两级,逐渐缩小宽度。这里有限的自相似分枝,就是这朵花的“分形”特征。

花脉上的点也使用花瓣的位置函数,再略微抬离表面。因此,调整开合进度时,花脉会随同一张曲面一起运动,不必为它另做一套动画。

花心则采用另一种排布方法:144 枚小晶粒按照近似黄金角向外排列,并逐步增大到中心的距离。这让晶粒在中心与外圈之间保持较均匀的分布。黄金角解决的是排布问题,与花脉的递归分枝各有用途。

先在浏览器里检查所有中间状态

为了方便试形,我们把几何数据和绘制代码放进一个独立网页。它通过 WebGL 2 显示花朵,提供花苞、半开、盛放按钮,也可以拖动滑杆、播放开合、旋转和缩放视角。

滑杆让一些问题变得容易发现。例如,两个端点都好看,半开时却可能出现花瓣交叉;正面看轮廓完整,侧面看又可能显得太薄。把动画停在发生问题的位置,再调整参数,比只看几张最终效果图更有针对性。

知微浅紫风格的 WebGL 数学样机,展示盛开的青紫花瓣、黄金色花心和开合控制面板
采用知微视觉风格的 WebGL 数学样机。可拖动开合进度、切换预设状态,并旋转或缩放视角,检查几何与配色。画面为独立网页预览。

网页样机把最频繁的造型试错放在浏览器中。它与游戏中的操作页面各有职责:样机用来研究花形,游戏页面则负责显示互动状态、发送控制指令。

本次保留的样机把几何数据和代码打包在一个约 6.5 MB 的 HTML 文件中,可以用支持 WebGL 2 的浏览器离线打开。文章末尾附有入口,可以直接拖动进度,观察形状是否连续变化。

把同一套数学规则带进 Unreal

形体确认后,Python 根据相同的规则采样,分别导出花瓣、花脉、花心和根须四份 OBJ。进入 Unreal 后,这四个部件仍保持独立,便于分别调整形变、发光、颜色和根部质感。

仅仅导入 OBJ,得到的还是一套静态网格。让它继续开合,需要把“每个顶点原本属于哪里”的信息一起带过去。本项目利用 UV 记录花瓣的层号、片号,以及点在花瓣表面的位置。材质读回这些信息,就能重新计算当前进度下的位置。

可以把这个过程写成一句话:

当前形态 = 盛放基准网格 + 当前状态相对盛放状态的位移。

Unreal 材质通过 World Position Offset,也就是顶点位置偏移,实现这一步。网页着色器和引擎材质使用同一套数学定义,便能从同一份盛放网格得到花苞、半开以及它们之间的连续状态。

主共鸣花网格统计
部件三角形数量
花瓣23,520
花脉37,464
花心1,152
根须6,084
主花合计68,220

这些数量对应主花的四份网格,不包含花盆、站位、角色和森林背景。约 6.8 万个三角形只是当前造型的实现规模,是否适合其他设备和场景,还需要结合实际渲染开销判断。

迁移过程中也有返工。早期尝试在编辑器中直接重建并合并网格时,遇到了渲染资源问题,后来改用标准 OBJ 导入和独立组件。单位、轴向、UV 精度和网格包围盒同样需要核对:数学公式一致,并不意味着导入后的显示会自动正确。

让互动进度驱动花开

到了运行时,花的材质只需要读取 Bloom。它不必知道两位参与者此刻做的是同步举臂、镜像动作,还是轮替接续;把这些活动转成进度,是游戏逻辑的职责。

当前实现把五段互动的阶段序号与阶段内进度合并,映射到 0 到 1。只要继续使用这个进度约定,后续调整互动内容时,就可以保留花的几何与开合方法。

场地嵌线的亮度、青紫两路光流的强度由另外的参数控制。光流还需要独立的暂停和恢复逻辑:把流速降到零,与真正暂停粒子系统并不是同一回事。当前接线设计在可靠的双人输入丢失时暂停计时和光流,并保留已经达到的花开进度。

这样,花朵就成为一种可连续调节的视觉反馈。它在正式双人体感活动中的表现,仍需要通过真实设备与参与者的现场测试来确认。

这次实验做到了哪一步

本次已经生成网页数学样机和四类网格,并在 Unreal 场景中验证了闭合、半开、盛放预览及四路光流的暂停、恢复。我们得到了一套能继续调整的形体和动画方法,而不是几张无法操作的效果图。

阅读和复用时,也需要保留这些边界:

这个案例提供了一条可以继续尝试的路线:先为形体找到清楚的状态参数,用网页检查变化过程,再把网格和同一套规则送入引擎。它也可以作为贝壳张合、羽翼舒展或机械结构展开的实现思路,具体造型与性能则要按项目重新调整。

AI 在这条流程中的价值,可以从交付物里检查:代码是否能运行,参数是否能改变形状,导出的网格是否能进入引擎,画面在中间状态是否仍然成立。把这些环节逐个落实,才让一个建模想法成为可以继续使用的作品。

支持 WebGL 2 的浏览器可离线运行;拖动旋转、滚轮缩放,或用滑杆观察开合。该页面是独立数学样机,不是 Unreal 实机。

实验说明:本文依据双生共鸣项目的数学建模文档、场景交付记录与现有源代码整理。配图来自网页样机和 Unreal 场景的实际画面。参数曲面、递归分枝、黄金角排布及材质顶点位移均为已有技术,本文记录的是它们在本项目中的组合与实现。