Houdini中的植物生成

介绍

大家好,我叫Kilian Baur,是来自德国的 CG 通才。

我一直对传统艺术技术很感兴趣,比如绘画、粘土雕刻或造型/铸造物体。在高中的时候,我对编程产生了兴趣,并使用 java 编写了许多非常小的程序。想要一份有创意的工作,我尝试了建筑学和计算机图形学。原来,CG 对我来说是艺术和技术工作(如编程)的完美结合。

在学习期间,我尝试了 3D 中的许多不同学科,例如动画、角色雕刻或纹理。但我一直最喜欢的是建模。我也开始学习 python 来自动化Maya 中的一些重复过程。因为我的两个朋友真的很喜欢Houdini并且制作了一些非常棒的东西,所以我也决定尝试一下。我做了一些项目,比如对棋盘进行程序建模,并生成了经典 8×8 网格以外的不同棋盘尺寸。 

RISE Visual Effects Studios实习并参与 Mike Flanagan 的 Doctor Sleep 工作期间,我真的学会了喜欢 Houdini 的程序工作流程。我开始在这个软件中做尽可能多的事情。 

程序方法

虽然我喜欢 3D,但有些任务在一段时间后会变得非常重复。有时,听音乐和移动一些多边形是很放松的,但我发现程序方法更有吸引力。这就像一个谜题,您正在解决问题并试图找到一种方法来使某些事情完全程序化。这就是我非常喜欢 Houdini 和编程的原因。他们都奖励更具技术性的思维方式。

由于程序设置通常比破坏性方法花费更多时间,因此在电影制作期间使每个资产完全程序化并不总是正确的决定。在家里做个人项目,我真的没有时间限制,可以挑战自己。

在创建一个新项目时,大多数时候我对如何处理它有一个松散的想法。每个项目的方法都不同。一般来说,我将项目拆分为更小的具体任务,然后尝试逐一解决。 

有时,我已经知道如何在 Houdini 中实现某些效果(来自教程或以前的项目),或者我可能会想到一种方法来实现它。然后,我必须弄清楚是否已经有节点可以解决我的问题,或者我是否必须使用 Python 或 Houdini 的表达式语言 VEX 来构建自定义解决方案。

程序化工作非常有趣,因为有很多方法可以解决每个问题,而每个艺术家可能会以不同的方式解决它们。与其他艺术家交流知识是学习新技术和工作流程的好方法。

即使某些方法没有按预期工作,您也可以后退几步并尝试另一种方法。因为一切都是程序性的,所以尝试一个想法并不会真正失去任何东西。

2 中的1

关于程序性多肉植物项目

在实习期间,我学到了很多关于 3D 的知识,但没有做个人项目。我想要一些较小的项目,我可以在几天内完成并展示我的一些新技能。

目前,我对植物的形状以及如何在 3D 中生成它们感兴趣。我学到了很多关于 L-Systems 的知识,它是描述植物生长的好方法,我想用它们做一个项目。在为这个项目寻找参考资料时,我发现了两张非常酷的多肉植物照片。

2 中的1

创造多汁植物似乎是一个有趣的挑战。起初,我只想创造“经典”多肉植物,但完成后,我决定测试我可以从我的设置中得到多少不同的形状。

另外,我想测试一些其他渲染引擎。虽然Houdini自己的“Mantra”有很多很酷的节点和着色功能,但它也以不是特别快而著称。尤其是渲染无噪声次表面散射 (SSS) 可能会非常痛苦。对于这个项目,我为 Houdini选择了Arnold,因为 Arnold 标准表面着色器是我的最爱之一,而且 GPU 渲染看起来很有希望。 

数学部分

每个项目所需的数学和脚本量是不同的。有时,很难找到可以构建其他进程的规则或依赖项。一些项目可能需要大量的向量数学,比如使用两个向量之间的角度或使用旋转矩阵/四元数来旋转对象。 

该部门的多肉植物非常简单。他们不需要任何复杂的数学。大多数数学由简单的乘法、除法和加法组成,我计算每个叶子的偏移量。这样每个级别的叶子均匀分布,然后我将它们稍微抵消一些变化。

另外,我计算了叶子的一些属性。它们基于控制植物整体形状的几个坡道。这样就很容易对植物的外观进行广泛的改变。

叶子生成

一般方法涉及创建单个叶子作为第一步。然后,我根据每个级别的叶子数复制并旋转叶子。最后,我对每株植物的级别数重复此操作。 

每个级别都有一些不同的叶子生成设置。这样,我可以创建有趣的形状。为了控制形状,我有一些参数。除其他外,我可以设置级别数、每个级别的叶子数或单个叶子的长度。

每个工厂级别的长度、宽度、角度等都不同。为了轻松控制这些属性,我有一个斜坡参数和一个浮点参数(浮点数)。渐变控制每个属性的形状。因为斜坡只能在 0 到 1 的范围内轻松控制,所以我还使用浮动参数来更改每个斜坡的幅度。

为了使用坡道,我将它们细分为工厂的层数。我读取每个步骤的值并将它们保存为数字数组。在生成叶子时,它们从与当前植物级别匹配的位置读取值。 

使用这种方法,我可以根据需要添加尽可能少或尽可能多的级别,而无需做更多工作。每株植物的层数越多,它就越接近坡道的形状。 

我通常采用坡道底部的叶子很小的方式。它们变得更高,在最后几个级别,它们再次变短。此外,每片叶子的弯曲在级别之间都非常剧烈。在较低的水平上,叶子几乎是平的,但弯曲度随着每一层的增加而增加,直到它们几乎形成一个封闭的形状。

在这个例子中,植物有 9 层,每层有 6 片叶子。第一层叶片弯曲10°,弯曲量达到110°。 

为了生成叶子,我从一条简单的线开始。我重新采样以获得更多分辨率并生成“curveu”属性。该属性的根值为 0,尖端为 1。使用这些值,我可以定义形状并最终为叶子添加一些颜色。 

基于斜坡,我将每个点在 Z 方向移动一定量以形成一般形状。我添加了一条中心线并使用“扫描”节点来创建叶子的一半。之后,我向上弯曲两侧并镜像它以获得完整的叶子。

我使用“polyExtrude”并稍微平滑位置以增加厚度。点位置上的噪声用于在每个叶子上添加一些变化。这样,即使它们在同一级别内,每片叶子看起来也有点不同。

在我弯曲叶子之前,它们通过简单地进行平面投影来获得它们的 UV。

为了添加更多细节并在背面中央创建一个可见的脊椎,我将中心线沿着它们的法线移动了一小部分。

在程序上找到所需的点并不困难。当我镜像两侧时,我使用了“熔断器”节点来组合两侧。熔断器节点能够输出一个只包含被修改点的组。这些是我用于中心脊柱的点。

使用从根到尖端的颜色渐变添加颜色。起初,我只想用颜色来形象化不同的植物。但我最终渲染了这个颜色属性,因为它已经足够好了,尤其是在添加了一些 SSS、凹凸和光泽之后。

整个叶子生成设置在两个循环内。内部的绿色循环重复进行,直到生成一层的叶子。外循环负责总级别的数量。使用当前级别,叶子从先前生成的数组中读取它们的特定参数(例如长度、角度等)。此外,我使用当前叶和当前级别为某些参数生成一些随机性。这样,每片叶子看起来都有点不同。

花盆和土壤

锅主要是程序性的。我不需要能够在建模后大幅改变其形状。这就是我为某些操作明确选择特定边的原因。

另一方面,土壤是完全程序化的,可以改变其高度。我采取的第一步是在所需高度剪裁锅几何。然后,我删除了所有不在里面的东西。我使用了“polyfill”节点并删除了除结果之外的所有内容,以获得正确高度的完美拟合平面。最后,我将几何体重新划分为许多偶数三角形并添加了 UV。在渲染过程中,我将该平面细分了几次,并使用Megascans中的一些纹理进行着色器和置换。

为了添加更多细节,我在土壤上撒了一些来自 Megascans 的鹅卵石。我能够实例化花盆和土壤 12 次,以减少渲染时的内存占用。重复是不可见的,因为它的大部分都被植物隐藏了。另一方面,每个锅的鹅卵石都是随机的,位置、大小、旋转和石头数量各不相同。

工作流的优势

按程序做所有事情的最大优势是能够相当快速地进行更改。我能够尝试很多不同的植物形状。我什至测试了 Houdini 的 PDG 以创建许多变化并了解我的英雄植物应该是什么样子。

使用过程依赖图 (PDG),我为植物生成创建了许多具有不同属性的楔形。每个植物都以极小的分辨率使用 OpenGL 渲染。渲染完所有植物后,它们会自动组合成一个巨大的图像。

最终的 12 个工厂中的每一个都基于相同的设置,只是一些不同的参数。唯一需要额外工作的工厂是带织带的工厂(见下文)。 

处理与几何相交的线

我首先尝试使用“连接相邻部分”节点,但这个节点有一个大问题。创建的线与植物几何体不切实际地相交。为了避免这种行为,我创建了一个新工具,用于在添加线之前检查潜在连接是否会与另一个几何体相交。

创建线条后,我将它们弯曲以使它们不太直,同时确保我不会添加许多新的交叉点。

这个工具的构建相当简单,因为我能够重用来自原始节点的大量代码。我添加了一些小功能,例如删除与几何相交的点,因为对于这些点,每条可能的线也会与某些东西相交。另外,这样我就不会创建完全在几何内部的线。否则,仍然会创建这些线,因为从技术上讲,它们不会与几何体的表面相交。 

为了检查连接是否会与几何体相交,我使用“相交”VEX 函数从起始位置向另一个点的方向发送光线。如果我得到一个交叉点,那么我不会创建一条线。

返回首页 

作者 CG-BOX

发表评论