[图形学] Hair Simulation in TressFX(头发模拟)
Posted ZJU_fish1996
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[图形学] Hair Simulation in TressFX(头发模拟)相关的知识,希望对你有一定的参考价值。
reference:《GPU Pro5》Hair Simulation in TressFX
人物的头发大约有120000根,由于渲染成本高和缺乏实时仿真技术,在实时视频游戏中呈现人类的头发一直是一个挑战。因此,许多艺术家和游戏开发人员必须选择其它方法,例如使用简单的多边形和纹理。
在本章中,我将解释TressFX中的头发模拟方法,该方法已在最近的Tomb Raider和AMD Rudy演示中使用。
在高端GPU中,它可以在不到一毫秒的时间内模拟大约19000个包含22万个顶点的线。TressFX专为影像游戏(video game)而开发,因此,性能是物理精度的最高关注点。
模拟概述
在开发TressFX模拟的时候,主要的重点是模拟塑型的头发,它比直发要硬的多,因为他需要更强大的弯曲和扭曲效果。无论是哪种发型,人物的头发都应被视为不可扩展的。为了模拟这三种效果,通常有两种方法来表示它们,也就是刚性弹簧或约束。
在VFX中,刚性弹簧通常用于各种仿真,例如头发或衣服。但是,对于实时物理模拟,刚性弹簧实际效果较差,因为强弹簧力的积分很容易使得质量弹簧阻尼器系统不稳定,除非使用复杂的积分方案,比如隐式后向积分器(implicit backward integrator)。而且,在同一求解器中很难处理拉伸、弯曲和扭曲弹簧,尤其是在GPU中。在Tress中,所有弹簧都被替代为硬约束和软约束。为了不可扩展性,我们使用一个简单的基于位置的迭代距离约束。为了简单起见,弯曲和扭曲被视为一个单一的影响,因此使用了局部和全局的形状约束。有时,我们也使用特殊约束(ad-hoc)来处理快速移动的角色。
除了弯曲和扭曲效果外,其它头发模拟与布料模拟类似。但是,如果使用GPU计算,对于头发更有利,因为有非常多发束,如果不考虑发束之间的碰撞的话,它们彼此是独立的。并且顶点连接的拓扑顺序是直接的。通过利用这几点,TressFX可以实现发束/顶点级别的并行,而无需复杂的数据结构。
定义
基本上,每根头发都是一条多边形线。在解释局部形状约束时,经常会使用局部和全局术语。全局位于世界框架中,局部位于局部框架中,该区域附加到线段的起点。
顶点索引从附着在头皮上的发束的根部开始。是当前时间步中顶点i的位置。第0时间是静止状态,我们使用右上标来明确表示它(即)。在这里,当我们解释算法时,我们只关注一组发束。因此,顶点索引i始终是唯一的。
如果需要明确说明我们使用的是哪个坐标系,则可以使用左上标来指定它(即表示顶点i在本地帧i-1中定义的当前时间步中的位置)。在世界坐标系中定义位置后,我们可以删除框架索引(即)
在变换方面,我们定义为包含旋转和平移的完整变换。它从转换为,以使
由于对发束中的顶点进行了小心的索引,因此以下方程式成立:
在这个章节中,我们称为局部变换,为全局变换。以顶点0为例,局部变换和全局变换是一样的,即
在图1.2中,本地帧定义在每个顶点上。向量和是当前时间步长下顶点i的本地帧的基向量。被简单定义为的归一化向量。更详细来说,.
在图1.3中,基向量显示为红色、黄色和蓝色。
为了描述头部变换,我们使用,它将头从idle状态转换到当前状态,并作为用户或预设动画的输入。
积分
为了对头发动力学的运动进行积分,我们使用Verlet积分方案,因为它与显式Euler方法相比简单且显示出良好的数值稳定性。 在此步骤中会施加外力,例如重力。 阻尼系数乘以速度即可模拟阻尼效果。 我们仅积分反质量为非零的粒子。 如果反质量为零,我们认为它是不可移动的,请在其附加对象(例如头部)之后更新其位置,然后跳过这些粒子的其余步骤。 我们为顶点0和1分配了零个逆质量,这样它们就可以随着头部移动而设置动画。
约束
有三种约束。
ELC(边缘长度约束)是模拟不可伸展头发的硬约束;
LSC(局部形状约束)是弯曲和扭曲的软约束;
GSC(全局形状约束)是LSC的补充,并以非常低的计算成本帮助保留了初始头发形状;
长度约束
ELC强制边保持它idle状态下的长度。图1.4显示了如何计算每条边的位置校正。为简单起见,我们对除前两个顶点设置相等的质量。为了并行应用此约束,我们创建了两个批次,每个批次彼此独立处理,因此可以安全地更新顶点位置而不会发生冲突。
在头发中,很容易将两个批次创建为偶数边缘索引组和奇数边缘索引组。我们运行第一批,然后运行第二批。这种方法为我们提供了良好的并行性。不幸的是,折衷方案收敛性较差,因此我们对其进行多次迭代,以使所有边缘均达到其静止长度。
在Tomb Raider中,主角可以快速移动和转弯。基本上,用户可以产生很强的加速度,从而导致很长的长发伸长。
在这种情况下,即使迭代超过20次,ELC也无法很好地收敛。通过测量第一个可移动边的长度并将其与静止长度进行比较,可以很容易地检查收敛性。
为了解决这个问题,我们切换到abhocyu约束,该约束仅更新一个顶点位置,如图1.4中的pi+。通过从发束的根部开始更新每个边的一个顶点位置,我们可以通过一次迭代简单地满足ELC。
但是,这种方法会给系统增加额外的能量,并导致不自然的仿真结果,为了消除这些多余的能量,我们增加了高阻尼。因此,我们仅在确实需要时才使用此方法,有兴趣的读者可以参考Muller,以便更深入地了解此问题和不同的解决方法。
全局约束
GSC的主要思想很简单。我们将初始头发形状作为目标,并尝试将顶点移动到该形状,它类似于形状匹配。
最容易理解的方式是将最初的头发形状看作是笼子,而GSC被迫使头发陷入其中。
在模拟开始之前,我们保存顶点P的其余位置。将idle位置用作目标位置,以应用全局形状约束。
在公式1.1中,SG是整体形状约束的刚体系数,范围从0到1.如果SG为0,则无效,如果为1,头发变得完全僵硬,并冻结为初始形状。
在许多情况下,我们在发束的一部分(例如靠近根部)上应用全局形状约束。 我们还可以从头发的根部到末端逐渐减少SG。 这是因为头发似乎在靠近根部时更加僵硬。 同样,它可以更有效地保持发型,而不会给整个头发模拟带来不必要的额外刚度。
整体形状约束的好处在于,它以最小的成本保持整体形状。 结合局部形状约束,几乎无需花费时间就可以完成模拟,并且在模拟开始时就不会出现视觉干扰。
设计师可以期望他们创作的头发形状将是初始形状。
整体形状限制还可以确保在快速移动的游戏过程中,头发不会缠结成怪异的形状。
局部约束
即使GSC可以有效地管理头发形状,我们仍需要一种方法来模拟单个发束的弯曲和扭曲力。在实时布料模拟中,弯曲效果通常表示为跨弯曲边缘连接两个顶点的软距离约束。也可以使用相同的方法在头发上产生弯曲效果,但是扭曲并不是很容易。
为了简单和高性能,我们将弯曲和扭曲效果结合为一种软距离约束。为了定义此约束,如图1.2和1.3所示,使用局部框架计算目标目标位置。
公式(1.2)由于其下标和上标可能看起来很复杂,但概念与ELC相同。第一个方程计算i-1di,它是当前位置与其目标目标位置之间的距离。左上标i-1表示那些位置在局部帧内定义。
最后,当我们计算位置校正时,我们实际上使用了世界空间,但是方程式(1.2)被写在局部空间中以简化它:
如ELC中所述,我们将位置校正除以质量比,并将其应用于两个连接的顶点(i-1Pi-1和i-1Pi)。 在这里,我们已经假设所有质量都相等,因此比率为1/2。
风和碰撞
风是模拟的重要组成部分,因为它使头发与环境互动,甚至在idle状态下也能赋予游戏角色动态感。为了产生更多随机效果并防止结块,将单个风输入转换为四个圆锥形方向,如图所示:
通过使用正弦函数和帧数来调制风的大小,如下所示:
公式显示了如何计算风力并将其应用于位置更新。W1,W2,W3和W4是四个风矢量,并且用于更多随机化:
第一个方程式中20是任意选择,W是四个风矢量中a插值风矢量,Δt是时间步长。
风是在形状约束之后施加的,而不是积分的一部分,因为形状约束太强并且如果在积分过程中作为外力施加,则可能会抵消其影响。计算风的关键是创建随机方向和周期大小。因此,它更像是一个经验性参数而非物理正确的。
资产
将发束创作为样条线后,自定义python脚本会将其导出为多段线。在TressFX演示中,头发分为前,顶部,侧面和马尾辫四组,每组保存为单独的文件。
GPU实现
TressFX在DirectX 11中使用计算着色器在GPU中运行头发仿真。
有五个计算着色器内核。清单1.1显示了Simulate Hair_A内核,该内核处理集成和GSC。该内核为每个线程计算一个顶点。由于GROUP_SIZE定义为64,因此,如果一个线程组具有16个顶点,则一个线程组可以计算四根头发。使用maxPossibleVertsInStrand,可以控制一个线程组中可以计算多少条线。由于GROUP_SIZE为64,所以一个线束中的最大顶点数为64。通过将GROUP_SIZE更改为128或256,我们可以拥有更多的顶点。但是,更多的顶点可能需要更长的时间来执行ELC和LSC。因此,建议为实时目的每条线使用16或32个顶点。
清单1.2显示了SimulateHair_A内核,它执行LSC。该内核为每个线程计算一个线程,因此存在一个for循环。 strandType是一个变量,显示该链所属的组。这样,我们可以为头发组分配不同的仿真参数,例如刚度或阻尼。
SimulateHair_C内核为每个线程计算一个顶点,执行ELC并施加风力。最后,SimulateHair_D负责碰撞并进行计算渲染管线的线段的切线。
如果应该忽略头发模拟,SkipSimulateHair内核实现了这一点。这也可以通过设置1.0的GSC僵硬度来完成,但这会浪费许多不用的运算。SkipSimulateHair内核仅在头部变换应用到顶点,并使头发进行刚体运动。
总结
TressFX的头发模拟在多方面针对实施游戏进行了优化,例如使用形状约束,以及对每个发束的顶点数的限制。因此,需要了解其基本方法,以使得其性能和质量最大化。
以上是关于[图形学] Hair Simulation in TressFX(头发模拟)的主要内容,如果未能解决你的问题,请参考以下文章
小球自由落体动态模拟(Position Based Simulation)
solidworks的simulation的result没有了
4.9-Simulation in gazebo or webots
fdtd simulation, plotting with gnuplot, writting in perl
[2016-05-18]OMG美语笔记-Do you like loose curls?What do you do to hold curl in your hair?
论文阅读笔记《Grounded Action Transformation for Robot Learning in Simulation》