人气 448

[图文教程] houdini河流(GAT+Horizon Zero Dawn) 笔记 [复制链接]

Alonnaapocact 2022-4-5 21:54:15

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
注:本文于2020-2-25日重新整理,补充了《地平线》的部分。
这两天看了下houdini河流相关教程。
一个是《地平线》(Horizon Zero Dawn)的:
Guerrilla Games | Horizon Zero Dawn
https://vimeo.com/216727778​vimeo.com/216727778









一个是它的仿制品:(GAT版)(GAT是Game Art Tricks的缩写)
GAT #69: River - 2k19 Edition
https://www.youtube.com/watch?v=OklvMqMCkc4&t=21s​www.youtube.com/watch?v=OklvMqMCkc4&t=21s









GAT版实现了地平线原版的一些主要特性(一些地方有所简化),并开源了工程文件。所以下面先说GAT版,然后再对照地平线原版查缺补漏。
一,总体流程
wl8qL02fGgEFyL8Q.jpg

二,GAT版
有于有源文件,直接看实现。下面记录一些要点:
1,curve与地形融合
就是把curve扔地形上自由下滑,最后得到一个看起来比较自然的形状:
XqkZ9DQc4K66i66Z.jpg

实现:
QIzee1NF7rR18PSe.jpg

可见是一个迭代过程,每次下滑一小点儿,反复迭代了60次。
对于每次迭代,先调整curve各点高度使其贴合地面并求出法线(adapt_curve_to_terrain),再让curve沿山坡下滑(slide_down_the_hill)。
adapt_curve_to_terrain内部实现:
fgDmbfgMAZrBlDKB.jpg

即:
P=(P.x,terrainHeight,P.z)
N=normalize(-terrainGradient+up)
terrainGradient是xz平面上的向量,指向爬坡方向。至于为什么法线等于normalize(-terrainGradient+up),见:杨超:由高度场求法线
另外,在vop里访问volume的用法很有用。
slide_down_the_hill的内部实现:
kCheZhdrkUZRmkzR.jpg

即:
T=cross(N,up)
B=cross(N,T)    (B就是滑落方向)
P=P+0.03*B
如图:
G61tr8kWIsL76ULk.jpg

2,确保‘水往低处流’
wqQxr5pKiK0rZfIF.jpg

就是沿着河的走向遍历curve上的点,时刻记录当前最小高度,如果当前点比最小高度高,就把它拉到最小高度,如果比最小高度低,就更新最小高度为此值。
3,生成阶梯
为河流增加阶梯形态(小瀑布),更符合人们对现实河流的印象。
bz6tpDcjdsfEJTbY.jpg

它是用fuse节点实现的:
nia97xdVXV9X8K3t.jpg

不过我看了一下,我自己创建的fuse节点跟它长得不一样(没有这个snap grid功能),估计它这个是老版本的fuse,现在已经改版了。但根据它的思路来看,应该是把Y轴分成了以0.5为间距的层,然后把curve的顶点按高度不同吸附到不同的层上,从而产生阶梯状。简单地说就是对y值做了个四舍五入,只不过不是以1为单位,而是以0.5为单位,于是试了一下:
OyP7pINVw7brN0wD.jpg

结果如下(几乎一样):
R28lSBe2OIxf8x5b.jpg

补充(2020-2-28):
网友(Katana For Lancet)提醒,现在的fuse节点也是有grid功能的:
fW9dPFdh5IQ5qi5q.jpg

4,标记瀑布
g0CADcOCs053eyM0.jpg

实现:
kk4lK1lB4C44FC8w.jpg

并不是忠实地计算梯度,而是把无梯度处标为0,有梯度处标为1。因为上一步已经阶梯化,所以只有台阶处有梯度。
另外在vop里获取下一个point的用法很有用。
注:pointimport可以根据ptnum获取顶点,还可以选择针对哪个输入的端。这是比bind强的地方。
5,河床mesh与地形融合
ZrH9shrT0iGAVS02.jpg

实现:
IjIijIBB7c06656j.jpg

即把地形下沉100,然后向上发射线,如果没命中(prim==-1)则用地形原始height,如果命中则取交点height。
vop里使用射线检测的用法很有用。
bind可以用于属性import也可以用作属性export。
6,标记河床
在融合了河流的地形上标记河床:
VDxMW1XllkfJlPEZ.jpg

即先生成河面,再由河面向地形发射线,后一步代码为:
rsnniGDDd1r7D9r1.jpg

在vex里做射线检测和打组的用法比较有用。
7,foammap生成
这块他弄得比较简单,就直接把障碍物颜色传河面上去然后再加个噪声,其中噪声是以add方式加上去的:
F85K5yAZdVa9kgZX.jpg

SCUZw0ZU7HFa24T4.jpg

P2R3Ksc1ajtrHN8r.jpg

8,flowmap生成
这部分用的是gamedev的现成节点。
先生成基础流向
用flowmap_guide节点,0号输入端传入河面mesh,1号输入端传入guide curve:
f3naAEorXoNJA3n3.jpg

内部是先用polyframe对curve求切线,再用attribtransfer把切线传给河面,作为流向v:
E4pQFI5razw46tcC.jpg

再考虑进障碍物阻挡
用flowmap_obstacle节点,0号输入端传入已生成了基础流向的河面,1号输入端传入障碍物:
UlLAnq2rxgG2snNa.jpg

内部是将障碍物转vdb,然后在pointvop里采样vdb获得法线,此法线与河面上的基础流向v进行合成(再加一个blur)作为新的v:
OFaOpq8kuf899ux9.jpg

最后flowmap长这样:
Gt11HIm2PC66iCHX.jpg

9,在障碍物周围摆放粒子系统
首先生成粒子系统的位置。
用intersectionanalysis求河面与障碍物交点,并通过fuse控制交点数量,这些点就是将来放置粒子系统的位置:
QERrv8E5v88CzE5D.jpg

另外把障碍物的法线赋到了交点上,如果没有流向v,这个法线就作为粒子系统的朝向了。(这里是用ray来获取最近几何元素的法线,比用xyzdist+primuv更省事儿)。
接下来将流向v考虑进来:
orient_particle_systems_according_to_flowVectors的0号输入即上面得到的粒子系统点(带有障碍物法线),1号和2号输入分别为 基础流向河面 和 带障碍物流向河面:
xx60mFFDbZMiMYMg.jpg

内部连线:
tL1m0yEg43e4ol2M.jpg

即:
设当前粒子系统点为P,其法线,亦即障碍物法线为N。
将粒子系统点移到高处,然后向下发射线去命中河面,用primuv获取命中点处的v值。
假设命中基础流向河面获得v_base,命中带障碍物流向河面获得v_obstacle。
这里插一步将N,v_base,v_obstacle的y分量都舍掉。
计算v_base与N的点积,如果结果大于-0.5,说明是障碍物后方或侧方,用v_obstacle作为粒子系统朝向(随波逐流了);否则说明是障碍物前方,用N作为粒子系统朝向(反弹了)。
考虑流向v前后对比:
hEYHh28dY2h4JUn9.jpg

将表示粒子系统的dummy物体拷贝到点上:
uhYMBhs8TOOhktt8.jpg

另外vop的set Attribute节点很有用,可以指定ptnum,可以指定输入端口,还可以输出group。(bind好像做不到)。
TYWRh9FTrsRyPs89.jpg

10,摆放反射球
这个很简单,就是把河流曲线resample了一下。
IWnpOO8KT43Ns1N1.jpg



三,地平线原版
没有源文件,但视频里讲得比较清楚,下面只说原版中与GAT版不一样的部分。
1,'水往低处流'
地平线版保证'水往低处流'的步骤叫做leveling,比GAT版复杂,分成了两个pass:
(1)erosion pass :顺流而下,一路将凸起压低(侵蚀)。(峡谷就是这么出来的)。
(2)fill pass:逆流而上,一路将凹陷抬高(填坑)。
另外其中引入的slope参数,是为了在“削平”的基础上再加一个“下行”的趋势。
Muk0U2nkBN2dKuo9.jpg

2,河流宽度
相比GAT版的等宽河流,地平线版对河流宽度的处理好得多。
地平线版河流宽受三个因素影响:
(1)ramp:用ramp来控制河流各处宽度。
D33nXZnCXuC3au17.jpg

(2)slope(坡度):slope越大水流越急,宽度越窄,反之水流减缓,宽度变宽。又通过exponent函数来夸大这种效应。
(3)canyon(峡谷):前面'水往低处流'一节中已经提到,erosion pass会侵蚀出峡谷,原始地形与河流曲线的高度差即canyon depth,canyon depth越大河流越窄,反之越宽。
三个因素作用下生成比较自然的宽度变化如下:
F2o8ZdYSONIYYGcB.jpg

3,生成阶梯
生成阶梯一步,在地平线版中叫做cascade(在GAT中叫stepping)。没有展开讲里面的实现,幸亏视频末尾显示出cascade的参数面板,为反推算法提供了很大的帮助:
SbxxF45KRyy78785.jpg

4,override机制
地平线版视频最后工程完善部分提到override功能,就是允许用户选择单独选择一些区段,对其中的参数进行覆盖重写,提供了更强的对局部精修定制的能力:
nlIJuaQ0iuJQ7uVS.jpg

5,其它
地平线版教程里,用vop+python,全程未出现vex,大佬的个人风格。GAT版继承过来,vex也用的比较少。我们自己改的时候没必要受这个束缚。


四,把漏掉的补回来
前面都是分析教程,下面动手干点儿实事儿。
我们在GAT版源文件基础上,参照地平线教程把漏掉的东西补回来,效果如下:
WrD1xzZH4H4084tV.jpg

viyI33RDD4aOd4RI.jpg

-------补充(2020-3-25):
OAUCC09VuNn90i3C.jpg

yaBlL6uu7PlLBqMP.jpg

Scqs6acA1Aq7sM1h.jpg

----补充(2020-4-20):
进ue里弄了一下材质,效果如下:

----2020-04-26
加了外围环境:
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|小黑屋|九艺游戏动画论坛 ( 津ICP备2022000452号-1 )

GMT+8, 2024-3-28 21:11 , Processed in 0.125309 second(s), 26 queries .

Powered by Discuz! X3.4  © 2001-2017 Discuz Team.