几何节点入门:用 12 个节点种一棵樱花树
不写一行代码,用 Curve to Mesh、Distribute Points on Faces 和 Instance on Points 拼出一棵会随风摇动的树。
三月的时候,我盯着一棵樱花树看了很久,然后打开 Blender,决定在电脑里再种一棵。
几何节点(Geometry Nodes)最迷人的地方,是它把「建模」变成了一种可视化的编程。你不需要画出每一根枝条,只需要描述它们如何生长。
这一篇记录我的第一个程序化作品:一棵风格化的樱花树。它不写实,但足够表达春天。
先理解「场」
几何节点的核心概念是 Field(场)。
想象你有一千个点,每个点都想问:「我的半径应该是多少?」场就是那个回答者:它不存储值,而是在每个元素上被求值。
这意味着同一个 Random Value 节点,可以给每个点不同的随机数;同一个 Spline Parameter,可以沿着曲线给出从 0 到 1 的渐变。
一旦理解这一点,节点树就不再是「连线游戏」,而是一段隐式的循环。
十二个节点的工作流
整棵树可以拆成四层:树干、枝条、花冠、落花。下面是核心节点清单。
| # | 节点 | 作用 |
|---|---|---|
| 1 | Curve Line | 生成树干的基础曲线 |
| 2 | Resample Curve | 把曲线重新采样成均匀的点 |
| 3 | Spline Parameter | 沿曲线输出 0 到 1 的参数 |
| 4 | Map Range | 把参数映射成从粗到细的半径 |
| 5 | Set Curve Radius | 写入每一点的曲线半径 |
| 6 | Curve Circle | 提供树干横截面 |
| 7 | Curve to Mesh | 把曲线挤出成实体网格 |
| 8 | Ico Sphere | 作为花冠的「代理体积」 |
| 9 | Distribute Points on Faces | 在花冠表面撒下花朵的位置 |
| 10 | Instance on Points | 在每个点上实例化花瓣 |
| 11 | Random Value | 给每朵花随机的旋转与大小 |
| 12 | Realize Instances | 需要编辑单个花瓣时转为真实几何 |
节点流向大致如下:
Curve Line ──▶ Resample Curve ──▶ Set Curve Radius ──▶ Curve to Mesh
▲ ▲
Map Range |
▲ Curve Circle
Spline Parameter
Ico Sphere ──▶ Distribute Points ──▶ Instance on Points ──▶ Join Geometry
▲
Petal Object + Random Value
第一步:让树干有粗细变化
添加一个 Curve Line,把起点放在地面,终点抬高到大约 4 米。接着:
- 用
Resample Curve把曲线分成 24 段。点越密,后面的半径过渡越平滑。 - 添加
Spline Parameter,把它的 Factor 输出连到Map Range。 - 把
Map Range的输入范围设为0 → 1,输出范围设为0.22 → 0.035。 - 将结果连到
Set Curve Radius的 Radius 输入。
现在树干从底部到顶端逐渐变细,像一根真正被风塑造过的木头。
半径是一个场。曲线上的每一个点都在独立地询问「我该有多粗」,而
Map Range负责回答。
第二步:给曲线一个横截面
Curve to Mesh 需要两个输入:曲线本身,以及一个 Profile Curve。后者决定横截面的形状。
添加 Curve Circle,把 Resolution 设为 12,半径保持 1。把它的输出连到 Curve to Mesh 的 Profile 端口。
注意:Set Curve Radius 的半径会与 Profile 的半径相乘。因此横截面圆的半径留 1,实际的粗细完全由曲线半径控制。这样修改起来更直观。
如果想要更有机的树干,可以把 Curve Circle 换成一条略微不规则的闭合曲线,或者在 Set Position 中叠加一点噪声。
第三步:复制出枝条
一棵树不能只有主干。最省事的做法是再创建两到三条 Curve Line:
- 起点落在主干的不同高度;
- 终点向不同的方向伸展,高度逐渐降低;
- 用同样的
Set Curve Radius逻辑,让枝条更细; - 最后用
Join Geometry把所有曲线合并,再统一做Curve to Mesh。
如果想让枝条的方向有随机性,可以在终点位置上叠加一个 Random Value,把类型设为 Vector,范围控制在较小的值。对于一棵风格化的小树,这已经足够。
第四步:在花冠上撒花
我不希望每一朵花都手动摆放。那会失去程序化的意义。
创建一个 Ico Sphere,细分等级设为 2,把它缩放成略扁的椭球,放在树冠的位置。这个球不会出现在最终渲染里,它只是花冠的代理体积。
- 用
Distribute Points on Faces在球体表面撒点,Density 设为 40 左右。 - 用一个花瓣模型(一个简单的弯曲平面即可)作为实例对象。
Instance on Points把花瓣放到每个点上。- 在 Rotation 端口接一个
Random Value,类型选 Vector,范围设为 到 。 - 在 Scale 端口接另一个
Random Value,类型 Float,范围设为 0.6 到 1.2。
这里有一个常见误区:随机欧拉角并不等于在三维旋转群上均匀分布。但对于花瓣这种小物件,视觉上没有人会拿尺子量它的朝向。工程上「足够好」是一种美德。
第五步:让风穿过节点树
静态的树已经好看,但我想让它呼吸。
给 Set Position 的 Offset 接一个向量,向量由 Noise Texture 生成:
- Noise Texture 的 Vector 输入接
Position; - 把 Scale 设为 0.6,Detail 设为 3;
- 将 Noise 的 Color 输出接到一个
Vector Math,模式选择 Subtract,减去 0.5,让位移有正有负; - 用一个
Vector Math的 Multiply 控制风的强度,例如 0.08。
然后让时间动起来:添加 Scene Time,把 Seconds 输出接到 Noise Texture 的 W 输入(先把 Noise 设为 4D)。
树冠会开始缓慢起伏。注意把 Set Position 放在实例化之前,否则每一朵花会整体平移,看起来很怪。
如果想连树干也一起摇,可以在
Curve to Mesh之前给曲线点加位移。但树干本身很硬,真实的树只有细枝和花会明显摆动。让一部分东西保持不动,风才有重量。
性能:实例,还是实体
Instance on Points 生成的是实例:Blender 只在内存里保存一份花瓣几何,渲染时重复引用。它非常快,适合成千上万朵花。
Realize Instances 会把每个实例转换成独立的真实几何。此后你可以对单个花瓣做编辑,但顶点数会爆炸。
我的建议是:
- 保持实例,除非必须对每朵花做不同的网格变形。
- 用 LOD 思路控制密度:远景的树 Density 降到 10 就够。
- 在视口里关闭暂时不需要的修改器,或者用简化模式。
一棵树,也是一个模板
把整棵树的参数暴露到 Group Input,它就不再是一棵树,而是一个树种:
Trunk Height控制高度;Branch Count控制枝条数量;Blossom Density控制花冠浓密程度;Wind Strength控制风。
我可以在一分钟内种出一片樱花林,每棵树都略有不同。这是程序化建模真正让人上瘾的地方:你不是在做一个物件,而是在描述一类物件。
最后
这棵树远不完美。枝条的分叉没有真正的递归逻辑,花瓣的分布也偏均匀。但它是我第一次感觉到,节点树可以像写诗一样被阅读:
先有主干,再有枝条,然后风来了,花就开了。
下一站,我想给这片林子打光。月光、霓虹和体积雾,应该会让它更像一个梦。
MARGINALIA
留言0
路过的话,留下一枚脚印吧。
BE KIND, BLOOM SOFTLY.
还没有留言。做第一个在这里留下脚印的人吧。