Houdini实现物体间连线
- 前期资产:
- ray节点
- 制作思路
- 问题与解决方式
- 求出没有遮挡的面
- 判定距离连线
- 最终效果
为了实现上篇文章效果:
Houdini使用Python给点连线.研究了一些教程.
这次提到的技术点出自
Cgcircuit - Applied Houdini Particle III视频教程.
适用于物体间连线,觉得技术点很好,特别记录下来,顺便理一理思路.
前期资产:
输入源:
object_GeoMaster(一个上下摆动的小球)
object_GeoOther(周围数个小球)
ray节点
在制作前,我们需要先了解一下ray节点,可以把它理解成投射节点.把A物体投射到B物体表面上.
它有两个输入端口:
- 投射出去的对象(后面简称投射体A)
- 接收的对象(后面简称接收体B)
Method参数有两个选项定义投射方式:
- Project Rays(沿法线投射)
- Minimum Distance(根据最近距离投射)
这两个选项一定要理解清楚,具体可以翻阅帮助文档.
Project Rays(沿法线投射)
Minimum Distance(根据最近距离投射)
制作思路
- GeoOther上发射粒子,控制数量和生命
- 创建ray节点将粒子投射到GeoMaster表面(Method:Minmum Distance)
- 创建ray节点将粒子投射到GeoOther表面(Method:Minmum Distance)
- merge两套映射后的粒子
- 创建add节点为两套粒子添加连线(By Attribute:id)
问题与解决方式
现在,我们用几个节点快速实现了物体间连线,但目前有几个问题.
- 发射范围:目前连线会有穿插模型的情况
- 距离:我们要让小球靠近的地方才会产生连线,远离的地方不会有连线
要解决第一点,我们可以通过求出没有遮挡的面
求出没有遮挡的面
这里会有一点抽象,
1把GeoOther通过Ray节点的最小距离方式(Method:Minmum Distance)投射到GeoMaster上
2创建AttributeWrangle将对应的两个点位置相减求法线方向
@N = point(1,"P",@ptnum) - @P;
3现在每个点法线都是朝向小球,如果我们使用ray的法线投射(Method:Project Rays),结果就和第一步的结果是一样的兜了一个打圈子,意义在哪里呢?
我们还是要使用ray的法线投射,但是接收体不再是GeoMaster,我们之前说过如果投在GeoMaster那么结果跟第一步一样.我们现在要投在GeoMaster和GeoOther的集合上,使用merge将GeoMaster和GeoOther合并,连接到ray的接收端
连完你会发现没有一点变化,目前投射端连的是处理过法线的GeoOther,接收端连的是GeoMaster和GeoOther的集合,结果就是投射端和接收端重叠,原地投射
我们只需要给ray节点的Bias参数一点点值,这个参数可以理解为投射的最小距离
结果如下:
会有这样的结果原因在没有被遮挡的点会被正常投射到小球表面,而被遮挡到就会被投射到前方的遮挡物,从而投射不到小球.
那么问题又来了,这样的意义何在?
答案是我们可以在GeoMaster定义一个属性作为标记,让投射到GeoMaster的点获取这个属性值,就能区分有没有被遮挡,进而求出没有被遮挡的面.快速动手下.
创建AttributeWrangle给GeoMaster定义属性
i@source = 1;
ray需要勾选从接收体导入属性
使用删除节点,删除刚定义的属性@source值为0的点,现在只剩下投射到GeoMaster上的点了.
把ray节点的TransfromPoint 关掉,得到如下没有遮挡的面
判定距离连线
现在解决第二点,我们要让小球靠近的地方才会产生连线,远离的地方不会有连线.
这个其实不难,我们试着想下ray节点可以控制投射的最小距离,是否也可以控制投射的最大距离.没错,看一下ray参数,确实是有最大距离选项可选.那么要加在哪一个ray节点上呢.?
我们只要在上面这个获取不重叠面的ray上勾选最大距离,调整一个合适的值,你会发现距离远的面被删掉了,因为它没有投递到GeoMaster上,也就拿不到我们定义的生存属性@source
最后的最后,把我们一开始的连线节点加上,就完成了我们要的效果.
最终效果