正文
前几天看到顽皮狗的特效师 “池田さま” 在 UnrealEngineJP 发了个教程,就是下图这样的效果,主要就是用 Houdini 做好的破碎然后导入 UE4,一大波操作之后做出来的效果。
很遗憾,我的 Houdini 才刚开始学,所以他的很多操作也没看懂,不过大致理解了他的思路,所以我尝试了用 Blender→UE4 的工作流来做这个破碎,好在我之前造了不少轮子,还是挺快就做出来的。需要说明的是,这种破碎还是代替不了 Chaos 的,因为他并没有碎片间的碰撞,适用场景应该是飞沙走石,地板破碎掀起那类的特效。
主要的 思路 是这样的,模型网格可以用我第一篇文章的做法来还原,碎块通过建模软件导出一个 csv 文件来管理,然后在 Niagara 用两个发射器,一个用来控制碎块的运动旋转,一个用来渲染。
一、Blender 的部分
在 Blender 进行破碎物体需要先开启自带的插件 Cell Fracture
然后点选物体(下图物体从 quixel 白嫖),进入 物体→快速效果→Cell Fracture
点击 确定 即可破碎,破碎后会分成很多个物体,我们需要把这些物体的位置记录下来,好在 UE4 进行还原。我们采用 csv 来记录,Blender 本身 并没有 导出 csv 的功能,不过 csv 是 Python 自带的模块,所以我们也可以用 Blender Python 来导出。
首先把破碎前的物体移开,然后框选所有破碎后的物体块,运行下面这块代码,他会把碎块按顺序先分好 UV ,然后把位置记录在 csv 文件上。(文件路径可以在代码的 with open 里面修改)
注意,上面的破碎插件有些瑕疵,破碎后有个别物体是不带网格点的,一般会在倒数几个物体上,请手动挑出来,当然不挑出来也不影响最终效果,只是运行代码后的 UV 存在空格,强迫症看着不舒服。
import bpy
import bmesh
import csv
from itertools import chain
sb=bpy.context.selected_objects
amount=len(sb)
bpy.ops.object.select_all(action='DESELECT')
for a in range(amount):
ob=sb[a]
me = ob.data
bpy.context.view_layer.objects.active = ob
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.uv_texture_add()
bm = bmesh.from_edit_mesh(me)
uv_layer = bm.loops.layers.uv.verify()
for face in bm.faces:
for loop in face.loops:
loop_uv = loop[uv_layer]
loop_uv.uv.x = a/amount+(1/(2*amount))
loop_uv.uv.y = 0.5
bmesh.update_edit_mesh(me)
with open('D:\location.csv', 'w', encoding='utf-8', newline='') as fp:
writer = csv.writer(fp)
writer.writerow(['x', 'y', 'z',"ID"])
for x in range(amount):
print(x)
writer.writerow([sb[x].location.x*100,-sb[x].location.y*100,sb[x].location.z*100,x])
运行后新建的 UV 层是下图这样的。
csv 文件如下
然后再次进入 物体 模式,再次框选碎片的物体,按 Alt + G 把位置复原在坐标原点。
再把这些物体合并,变成一个物体,就可以导出了。
二、 UE4 的部分
我们要处理 csv 文件,请先打开自带的 Houdini Niagara 插件
然后把 Blender 导出的 csv 文件,修改后缀为 .hcsv 再导入,这样可以伪装成 Houdini 生成的 csv 文件。
导入上面生成的 fbx 文件时把它导入为 骨骼网格体,因为在 Niagara 的 API 上骨骼网格体可以读取到更多信息。
创建如下一个模块来还原碎片的位置。
创建一个发射器,把导入的 hcsv 文件给模块输入,就可以还原碎片的位置了。
接下来需要渲染碎块,我是直接从以前的网格破碎里面魔改的,大家可以先看看之前的文章《UE4 niagara教程--网格破碎》 再继续。
还原网格的模块主要有 两块修改,增加了粒子属性阅读器,从上面一个发射器读取位置和旋转,ID 根据之前在 Blender 处理的 UV 来运算,因为碎片在 Blender 导出前就归位到原点了,所以位置加上 csv 读取的数据就能还原位置,而旋转加在三角面读取的三个点的 position 上面,所以都是以原点为基点来进行旋转。
材质的话没啥变化,还原的效果如下图,第一个发射器不用渲染,只用来处理碎片的位置旋转运算。接下来只有第一个发射器的事了,无论怎么运动,碎片都有正确的运动和旋转。
增加一些力场,做一些简单的效果,最终效果如下图。