游戏《孢子》的思考 —— Metaball的逻辑,实现及对应思考
2017-11-22 21:20
435 查看
这篇博客介绍了Metaball对应的逻辑,以及我相关的思考。
那么这样一来,我们预先设定一个强度,并且绘制出三维空间中的等势面,这个等势面就是一个Metaball。
如下图,可以看出来针对于Metaball来说,当他们相互靠近时,对应的那些顶点会被彼此的控制点影响。
当控制的图元不再是点,而是一条线段或者一个平面时,那么r通常取空间中的点到这条线段或者平面上的最短距离,例如下图就是不同场强度的Metaball。
对于线段的控制图元来说,一个可能出现的问题在于交界处的融汇。如果只是简单粗暴实现,有可能导致在两根线段交汇处出现鼓起的情况,例如下图的最下面的情况:
有些时候,这种鼓起来的状况并非开发者所期待的,开发者更期待的可能是两条线平滑融合……这种情况可以使用各种不同的Blending Function来解决。
因此,可以考虑将在一段距离之后,将对应的场强直接设定为0。这样一来,就可以节省一些计算量了。
因此Metaball的公式可以设定为:
f(r)=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪a(1−3r2b2)3a2(1−rb)200≤r≤b3b3≤r≤bb≤r
a为缩放比例,b为控制点生效的最大距离。
在另一篇论文中,有一个更加简单的实现方法:
f(r)=⎧⎩⎨⎪⎪a∗[1−r2b2]20r≤botherwise
这种方法比较简单粗暴,但实际上效果也不差。
f(r)=⎧⎩⎨⎪⎪f(r)=a[(r)2b2−1]40r≤botherwise
至于为什么要使用4次多项式呢?在开发者的博客提到,是为了获得更加连续的导数,从而避免光照的情况下出现不连续的状况。原文如下:
They use a 2nd order polynomial, but we square the main term again to get more continuous derivatives to avoid lighting discontinuities.
另外说一声,对应的Implicit Surface我已经封装成插件了,Github传送门。
因此做法很简单,直接创建一个
<全文完>
背景
在游戏《孢子》中,由于游戏要处理的是完全不可预测的,由玩家决定的Skeleton Mesh,因此当玩家改动或增减了躯干时,需要实时重新生成对应的蒙皮信息。因此在《孢子》中使用了Blobby implicit surface(一般也被称为Metaball)来表示蒙皮信息。Metaball的介绍
考虑场函数D(r)=1r2和在3D空间中的一系列控制点。其中r指的是三维空间中的某一个点到控制点的距离,而在场中对应的强度则可以认为是这一系列控制点所产生的场强度的总和。那么这样一来,我们预先设定一个强度,并且绘制出三维空间中的等势面,这个等势面就是一个Metaball。
如下图,可以看出来针对于Metaball来说,当他们相互靠近时,对应的那些顶点会被彼此的控制点影响。
当控制的图元不再是点,而是一条线段或者一个平面时,那么r通常取空间中的点到这条线段或者平面上的最短距离,例如下图就是不同场强度的Metaball。
对于线段的控制图元来说,一个可能出现的问题在于交界处的融汇。如果只是简单粗暴实现,有可能导致在两根线段交汇处出现鼓起的情况,例如下图的最下面的情况:
有些时候,这种鼓起来的状况并非开发者所期待的,开发者更期待的可能是两条线平滑融合……这种情况可以使用各种不同的Blending Function来解决。
Metaball的实现
Metaball在项目中的实现往往要考虑性能的开销。场函数往往是可以延伸到无限远处的地方,但这样会导致计算量的快速增长。因此,可以考虑将在一段距离之后,将对应的场强直接设定为0。这样一来,就可以节省一些计算量了。
因此Metaball的公式可以设定为:
f(r)=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪a(1−3r2b2)3a2(1−rb)200≤r≤b3b3≤r≤bb≤r
a为缩放比例,b为控制点生效的最大距离。
在另一篇论文中,有一个更加简单的实现方法:
f(r)=⎧⎩⎨⎪⎪a∗[1−r2b2]20r≤botherwise
这种方法比较简单粗暴,但实际上效果也不差。
孢子的Metaball实现
查了一些资料,发现孢子的Metaball的公式并不是上面提到的任何一种,而是如下:f(r)=⎧⎩⎨⎪⎪f(r)=a[(r)2b2−1]40r≤botherwise
至于为什么要使用4次多项式呢?在开发者的博客提到,是为了获得更加连续的导数,从而避免光照的情况下出现不连续的状况。原文如下:
They use a 2nd order polynomial, but we square the main term again to get more continuous derivatives to avoid lighting discontinuities.
在UE4中的实现
考虑到在先前的博客中已经在UE4中实现了Implicit Surface的绘制了,那么就可以通过这个方法来绘制Metaball了……另外说一声,对应的Implicit Surface我已经封装成插件了,Github传送门。
因此做法很简单,直接创建一个
MeshComponent继承自
UImplicitSurfaceComponent,然后重写对应的
ImplicitSurfaceFunction函数即可。
<全文完>
相关文章推荐
- 逻辑思考题之10个硬币游戏的讨论
- 谈谈我们的游戏逻辑服务器实现(一)
- 思考的救赎(一):三消游戏实现探索
- Asp.net MVC权限设计思考 (二)逻辑部分实现
- 游戏世界服逻辑的实现
- list实现的排行榜 针对游戏逻辑
- Unity 2D游戏开发教程之使用脚本实现游戏逻辑
- Unity 2D游戏开发教程之使用脚本实现游戏逻辑
- 三消游戏核心逻辑的一种实现
- 游戏《孢子》的思考 —— Ear Clipping算法
- 最简单的游戏回血逻辑实现(包括源代码)
- ios实现一个射击游戏,逻辑分析与对象的提取
- 游戏业务逻辑和DB无阻塞实现
- 游戏任务成就体系的实现(八):用户获取任务信息逻辑组
- 疯狂ios讲义疯狂连载之实现游戏逻辑(2) 推荐
- 【cocos2d-x制作别踩白块儿】第七期:实现游戏的逻辑
- Asp.net MVC权限设计思考 (二)逻辑部分实现
- 疯狂ios讲义之实现游戏逻辑(1)
- 简单的游戏逻辑,用C++ console来实现简单的逻辑
- 【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现