【译】 【Agni-s Philosophy】使用的图形技术解说(中篇)

发表于2016-03-11
评论0 1.8k浏览

 

  2012年11月23日到24日举办的【SQUARE ENIX 开放会议 2012】中,提出了很多暗示次世代游戏开发的最新技术,继续前篇的,是在开放会议第2天进行的,关于【Agni's Philosophy】的实时图形技术解说会议的中篇介绍。 

  前篇中,是对Agni's Philosophy的基本信息,以及【渲染管线的细节】【阴影生成】【全局照明】【环境光的自遮蔽】【皮肤表现】【眼球Shader】解说部分的报告,这次的中篇,主要是Agni和老人角色使用的毛发部分的解说。

    第一篇:Agni's Philosophy】使用的图形技术解说(前篇)

    第三篇:Agni's Philosophy】使用的最新图形技术(后篇)

Remi Driancourt(SQUARE ENIX 技术推进部 高级研发工程师)

 

制作头发和胡须的最新技术(1)~【线段方法】和【香蕉叶方法】

虽然存在感很普通,但要表现真实面部外观的重要的要素,就是【毛发】和【胡须】。现实世界里,【假发】和【假胡子】很容易被识破,人类【对脸的观察】是非常严格的。

所以,在Agni's Philosophy中,胡须和毛发的表现,也是要相当留意制作的部分,实际上,技术上挑战的部分也很多。

 

毛发的构造与光的传播模式图

 

Remi Driancourt氏介绍了关于头发的表现在实时3D图形的实现方面的几种技术。    

第一种是,负荷比较高的,近年来在高端GPU上实现了的方法【全部头发用线段(Line Strip,Strand)来表现的方法】。

第二种是从PlayStation 2时代开始使用了10多年的古典的方法,用合适大小的板型多边形贴上毛发的Texture,在把这个作为一块头发来植入的方法。日本这种方法一般被称作【毛ヒレ(鳍)】,技术推进部把它称为【Banana Leaf】。 

还有一种Driancourt氏没有介绍的毛发表现经常使用的方法。就是把毛发的断面图的Texture使用在堆积多层的多边形上来渲染的方法。称作Shell方法,近年来在动物的体毛表现使用的方法。

    

Agni's Philosophy的毛发表现,采用的把是Banana Leaf和Line Strip两种方法用LOD混合使用来实现

 

话说回来,Driancourt氏在这用Line Strip表现和Banana Leaf来表现的方法里进行选择,决定适当的把两种方法组合来使用。 

因为线段方法有着负荷高,而品质也很高的特点,另外,Banana Leaf的方法的表现,比Line Strip的方法差,但可以低负荷的作出简单有体积感的毛发表现。这样,实际两种方法的使用的话,远景的时候增加Banana Leaf的使用率,进行LOD(Level of Detail)的控制,构筑了在品质和性能之间灵活变更的结构。

 


没有头发和胡子

 


只有Banana Leaf方法的头发

 


Banana Leaf方法制作的头发和Line Strip方法的头发组合的状况

制作头发和胡须的最新技术(2) Line Strip方法头发的模拟和Tessellation

前篇中也提到了,本作的【毛发】和【胡须】,是角色在【Maya】上进行3D建模是加入NURBS(Non-Uniform Rational B-Spline)曲线的控制点参数,在直接继承到Luminous Studio的实时渲染引擎里的形式进行绘制的。

由于角色运动或其他原因导致头发和胡须摇动的情况,对这个NURBS曲线的控制点使用物理模拟和动画。

 


 

给予头发运动的处理,把这个【NURBS控制点】作为粒子来看,用弹簧链接进行基本的弹簧物理的实现。因为旋转控制点不合适时变得不自然,避免这个在各个Joint部位加入角度控制。还有,基于粒子的弹簧物理是在GPU里用GPGPU进行的,几乎没有使用CPU

 

 

毛发的物理模拟

髪の毛の物理的な挙動デモ

用GPGPU实现的弹簧物理模拟来控制的主人公Agni的毛发。后半部分老人的胡须Demo中,可以看出毛发也有进行碰撞判断的样子。

虽然头发的NURBS控制点的位置可以很好的对用动画,但如果直接这样连接的话,就会变成折线一样的头发。而这里需要【柔顺的头发】。立刻想到了使用DirectX 11中增加的可编程Shader【Tessellation Stage】的方法,Agni's Philosophy中,使用了DirectX 11平台的GPGPU功能【Compute Shader】进行头发的Tessellation。

 


制作【柔顺头发】的Tessellation处理,是用Compute Shader进行的。

 

在Maya建模阶段加入的 Line Strip方法的头发和胡须,实际上并不是全部的毛发。制作的,可以也可以说是“代理”毛发和胡须,这样直接绘制的话,根数不足可以透过看到皮肤,感觉是【非常薄的毛发】状态。

这样就必须要进行【增毛】处理,也就要增加头发的线段(Line Strip)。

说到【增加线段】,一般会考虑使用Geometry Shader来进行多边形的增点,不过Agni's Philosophy的增毛是在Tessellation Stage中进行的,继之前的【使用Compute Shader做线段的分割】后,也是出乎意料的实现。

【Tessellation是把多边形做细分的Shader Stage】理解的话,但【用Tessellation Stage增加线段】的说法可能就难以理解。

知道DirectX 11的Tessellation Stage,作为分割对象的图元( primitive)除了三角形和四边形外,还有线段可以选择的人应该很多。实际上,这时是把输入的线段生成感觉像平行线一样的等高线(Isoline)。


 

俄勒冈州立大学的论文,Tessellation Pattern的图解    


http://web.engr.oregonstate.edu/~mjb/cs519/Handouts/tessellation.6pp.pdf

 

Isoline Tessellation输入的线段生成等高线,NVIDIA的Sarah Tariq的论文


http://sarahtariq.com/presentations.html

 

Agni's Philosophy中,线段生成的头发是用Tessellation Stage的Isoline Tessellation来进行增发处理的

 

这种用【Isoline Tessellation】复制增发的线段头发,如果不做处理看起来就像是工整排列的【成簇的头发】。只是单纯表现的话,或许这样就可以的。

但是,也可以在Domain Shader中,把复制的头发分别向不同方向变化。例如,螺旋状变化的拉斯塔法里式发绺(Dreadlocks),用适当的振幅变化,来实现卷曲的头发。总之,是对【Isoline Tessellation】中生成的平行线进行Displacement Mapping那样的印象。 

作品中开头出现的老人生动的胡须,就是通过这种方法来实现的。

还有,改变变化的方式,还可以作出下面动画里看到的变化丰富卷发的表现。

    

对每个线段头发进行Displacement Mapping也可以作出卷发的表现

  

胡须运动的生成和模拟

髭のインタラクションデモムービー

胡须碰撞判断的显示,卷曲胡须的生成演示 

增加毛发让外观变的丰富,不过毛发在画面上的粗细平均也只有1个像素,角色距离相机远或近,头发和胡须的外观就变得不稳定,为了改善这个问题,Driancourt氏加入了使用Geometry Shader让线段多边形化(Billboard化)的处理

具体里的,是对于构成头发和胡须的每个线段的两个顶点,用Geometry Shader 增加两个顶点,变化为4变形。 

因为Billboard化也变得有面积,可以像Banana Leaf方法的头发和胡须那样贴上Texture。所以,阴影处理的效果,也是Banana Leaf方法所带来的整体感的附加优点。

 

线段的毛发和胡须最终通过Geometry Shader增加顶点来多边形化

 

不论是头发还是胡须,实际在Agni's Philosophy中,是用Compute Shader,Tessellation Stage,Geometry Shader等新技术一起来实现的

 

头发和胡须的渲染管线,把Compute Shader,Tessellation Stage,Geometry Shader一起使用来渲染

 

另外,Driancourt氏提到,这里解说的头发和胡须的生成方法基本上都是参考了NVIDIA的Sarah Tariq氏的论文,想了解更加详细的话请参考这里。http://sarahtariq.com/presentations.html

 

没有胡须

 

在Maya建模时使用NURBS控制点直线连接的胡子

 

使用Compute Shader进行Tessellation处理后的状态

 

在Tessellation Stage中实现 等高线(Isoline Tessellation)后的增加毛发的状态

 

进一步强化增加毛发效果

 

利用Tessellation Stage的Domain Shader,把毛发末端捻在一起加入位移变化。

 

扭曲变化的卷发

 

加大扭曲幅度(降低频率)的状态

 

毛发末端给予分支的控制,变成分叉

制作头发和胡须的最新技术(3)头发胡须的阴影处理

实际的头发,是细微的圆筒状,半透明的,在这个表面产生镜面反射。这时,产生的高光,CG称作一次高光(Primary Hilight),比起发色的影响,它受光源颜色影像更强烈。

而且,渗透到头发内的一部分光,受到头发本身颜色的影响再射出。这个出射光,在视线上增加了第二次高光。

渗透到头发中的光,再从头发中透射出来。因为是从头发中渗透的,比起光原来颜色,高光受毛发颜色影响更大。

关于毛发这种特殊的阴影处理,加州理工学院的James T. Kajiya在1985年的论文【Anisotropic Reflection Models】非常有名,现在Kajiya-Kay的着色模型也成为了毛发渲染的参考。 

Driancourt氏在去年的开放会议时,揭露是用Kajiya-Kay方法来实现的,由于有在制作阶段要求美术师可以修改高光的要求,切换成了基于康奈尔大学的Steve Marschner的论文【Light Scattering from Human Hair Fibers】的方法。Marschner方法在SEGA和Tri-Ace的游戏【永恒终焉(End of Eternity)】中也有使用,算是近年来使用案例增多的一个技术。

http://graphics.stanford.edu/papers/hair/

 


Agni's Philosophy的毛发阴影处理采用了Marschner的方法

 

Marschner方法的阴影处理最核心的地方,就是毛发的切线向量(Tangent)。通过摄动切线或位移,使阴影产生变化,调想要表现的发质。

Driancourt在在下面的截图里提到的具体示例,修改切线向量,给发质粗糙的感觉,或按一定方向位移,移动高光的出现方式,

    

关闭Marschner方法,左边是Line Strip方法,右边是Banana Leaf制作的头发

 

打开Marschner实现的一次高光

 

打开Marschner实现的二次高光

 

位移切线向量的例子,高光整体向发梢端移动。

 

给予切线向量噪波晃动的示例,头发变得粗糙

 

黄色光源阴影处理的结果

渗透到头发里再射出的二次高光,有意图的产生颜色的偏移

 

然后,是对Agni's Philosophy的头发和胡须,使用Line Strip的生成方法,与Banana Leaf方法的基于多边形的混合技术的说明。    

Driancourt提到接下来要解决的,是用两种不同生成方法的头发和胡须外观的一体化,变得没有不协调感。既有Line Strip,又有Banana Leaf,没有处理的话就会看起来像【两种头发】。

特别成问题的是,两种方法制作的头发,使用环境CubeMap时反射周围环境的表现,以及使用前篇中解说到的全局照明系统光照后的不一致感。   

这个主要问题的,是线段(Line Strip)方法的头发。最初的线段方法的头发,并没有表示【面朝向】的法线向量。这样,就需要计算出【两个虚拟的法线向量】,再合成来使用。一个法线向量是由切线向量和视线向量的外积来求出,还有一个向量,是这个要阴影处理的像素坐标和头发区域中心坐标(Bounding Box的中心)来计算求出。

前者法线是对应视线移动计算出的大幅变化的特性,后面的法线是相反的相对移动变化稳定。Agni's Philosophy,就是把这两个法线合成来获取他们的中间特性。

 

两种方法计算出虚拟的法线向量

 

切线向量和视线向量的外积求出虚拟法线向量

 

阴影处理的对应像素的坐标与毛发空间中心坐标(Bounding Box的中心)计算求出虚拟法线向量。

 

两个虚拟法线向量合成的结果

 

下面展示的是,实际使用了前篇介绍的用SH  Irradiance Volume做全局照明效果的画面,和使用环境Cubemap的画面的截图

Line Strip和Banana Leaf两种方法的头发阴影的表现和Driancourt考虑的一样,有很大差异,但结果确实是很接近的结果。

    

左边是Line Strip,右边是Banana Leaf方法制作的头发,两者全局照明效果的对比。

 

右边是Line Strip,左边是的Banana Leaf的头发(从后面看所以左右变化了)。两者全局照明效果的对比。

 

左边是Line Strip,右边是Banana Leaf方法制作的头发。使用环境Cubemap的结果比较。

 

右边是Line Strip,左边是的Banana Leaf的头发(从后面看所以左右变化了)。两者使用环境Cubemap的结果比较。

 

之间的解说演示

Agni's Philosophyの髪の毛デモ

制作头发和胡须的最新技术(4) 头发和胡须的性能和LoD控制的导入 

Driancourt也提到了关于Agni's Philosophy的头发和胡须的生成手法的运行性能

开头登场的老人角色,建模阶段设定的胡须根数是295根,加入了1656个NURBS控制点。把这些用Compute Shader进行Tessellation,1656个点数据增加到7100个。执行Tessellation Stage的Isoline Tessellation增加100倍的毛发,顶点增加到了71万个。

性能的汇总在下表。数值单位是ms。    

 

头发和胡须的绘制性能

 

这个表需要稍微做些介绍,横轴,是用Compute Shader和Tessellation Stage组合进行毛发增加处理的倍数1~100倍的参数表示。这里显示的就是实际的顶点数量,纵轴是用Geometry Shader做Billboard化时【Billboard的宽度(头发的粗细)】参数从0.1~2.0,实际显示的像素数量。

Driancourt氏指出,通过这个性能测量表可以作为对应角色和相机距离关系的Lod(Level of Detail)的控制标准。给予【头发根数】x【头发的粗细】值,假设显示的【视觉的头发数量】,再检讨如何选择绘制标准。 

把前面的幻灯片中【头发的根数】x【头发的粗细】=10的数据提炼到下面的表,通过这表,可以了解要获得毛发的体积感的设定【头发根数多负荷高】

 

给予【头发的根数】x【头发的宽度】值,假定表现的【视觉的头发数量】

 

总之,按照角色和相机的远近关系,减少【头发根数】的增加数量,提升【头发宽度】来获得更好的性能。Agni's Philosophy中就是加入这个LoD标准来实现的。

 


有无LoD控制的比较。外观没有什么变化,有LoD的性能提升了2.5倍。

制作头发和胡须的最新技术(5)头发和胡子的影子生成

Agni's Philosophy中,关于头发和胡子的影子生成,用的方法虽然简单,但也是相当的认真来实现的。

头发和胡子投射的自阴影,使用的是基本的基于Percentage Closer Filtering(后面简称PCF)的加入Soft Shadow处理的Depth ShadowMap技术。绘制每个毛发的像素时,判断【是不是影子】,并不是YES/NO的而知判断,而是对应这个像素到遮蔽物的距离来决定阴影颜色的浓淡。具体的,内次的毛发显示出深的影子,接近外侧(光源)的毛发阴影更亮。通过增加这个处理,可以作出有虚拟的周围光和透过光影响的表现。

 

头发和胡须的阴影生成算法,采用的基本的Depth Shadowmap技术,对应遮蔽物的距离来加入阴影,表现出毛发的透明感

 

还有,生成Shadowmap所需要的深度缓冲(Depth Buffer)渲染的对象,并不最终生成毛发和胡须,而是把【毛发的根数】极端的消减,【毛发的粗细】极端变粗的状态下来生成的。这样影子的显示更加稳定,同时也减轻了负荷。这种负荷的减轻,看完前段分析的应该也会明白了吧。

 

生成Shadowmap是在极端消减【毛发根数】,极端变粗【毛发粗细】的状态下进行的。这样阴影的样子更加稳定,性能也提升了。

 

下面是,增加了自阴影的胡须渲染的结果。

没有自阴影的胡须

 

有自阴影的胡须

 

有自阴影的胡须,强调阴影渐变的模板

 

制作头发和胡须的最新技术(6) 头发和胡须的后处理特效

Driancourt也提到了,Agni's Philosophy中采用的反走样(Antialiasing)的配置,Agni's Philosophy中,Antialiasing方法采用的是8 x MuiltiSample Anti Aliasing(MSAA),以及FXAA(Fast Approximate AntiAliasing)并用。

 

Agni's Philosophy的Antialiasing策略。景深(Depth of Field)严格来说是不需要的AA的,为了降低影像模糊结果的锯齿感,这里也列了出来。

FXAA是在PlayStation 3和Xbox 360的游戏上采用的更先进的屏幕空间处理的AA方法,检测渲染结果在垂直水平方向上的亮度差,如果有亮度差就用渐变来模糊的算法。 

可能觉得8 x MSAA就足够了,但MSAA有沿多边形的轮廓像素素横切时无效的特性。MSAA,是把Pxiel Shader 1次的结果,用8倍的分辨率(8x MSAA就是8倍的分辨率)的深度缓冲采用,判断出轮廓进行反走样处理。像素边界与多边形轮廓正好吻合的话,这种AA就没有效果了,也就会产生众所周知的Artifact。相机上下移动或左右平移的影像,会有一定节奏的像素边缘的明显化。 

本作使用了很多的头发和胡须,因为有着细小的几何体构造,很容易出现这种Artifact。FXAA可以把渲染结果直接使用Anti Aliasing处理,起到了降低Artifact的作用。

 

没有AA

 

使用 2x MSAA

 

使用 4x MSAA

 

使用 8x MSAA

 

使用 8x MSAA+FXAA

 

使用 8x MSAA+FXAA + DoF后的最终画面。

 

由于Agni's Philosophy的头发和胡须,使用Banana Leaf方法的毛发是在多边形上应用Texture,因为使用的是有半透明信息的Texture,这个的绘制品种也要注意。

Driancourt氏提到“当初也考虑到把Banana Leaf方法的多边形头发用远近来排序,不过看到主人公Agni的发型的复杂而放弃了”。最后,选择了【Alpha to Coverage】的现实的方法。 

Alpha to Coverage是对应Pixel渲染有透明信息时,考虑透明度进行MSAA处理,是DirectX 10以后的GPU标准配备的功能。

Alpha to Coverage的效果是,使用了有透明要素的Texture的多边形,可以正确的AntiAliasing,顺序混乱的透明的Overwrite也可以获得不错的效果。因此,包含毛发那样的半透明的物体对象的Overwrite绘制都使用这个技术。

例如,负责SQUARE ENIX制作, BYKING负责开发的【GUNSLINGER STRATOS】中,角色的头发绘制也使用了Alpha to Coverage

 

头发的绘制使用的【Alpha to Coverage】

 

还有,绘制为了增加对比感,还使用了图像空间的后处理特效【Unsharp Masking】。具体的,头发和胡须部分有深度值的差的时候,对阴影进行加强处理。

 

头发和胡须使用Unsharp Masking

 


使用Unsharp Masking前后的比较

 

各向异性反射的阴影处理

Agni's Philosophy中,一部分材质采用了各向异性反射的光照模型,各向异性反射,是根据观察素材的视线角度改变反射特性的反射模型,在毛发和粗糙的金属材质表面上可以看到。对应视线角度的各向异性反射参数一般是存放在Texture里。

最终的影像上,主人公Agni和祈祷师角色【Sidoro】穿着的绸缎服装就采用了这种发射模型

 


衣服的反射模型使用了各向异性反射

 

Agni的礼服的各向异性反射模型

 


关闭各向异性反射和打开的状态比较

 

各向异性反射的演示

異方性反射のデモ

下面,是使用了前篇提到的全局照明,皮肤,眼球渲染的技术,以及这次介绍的毛发和他的AntiAliasing,PostEffect,各向异性等技术渲染的Agni's Philosophy,与Visual Works制作的预渲染版的Agni's Philosophy的比较的画面截图。

 

    

主人公Agni,几乎是同样的外观。

 

祈祷師Sidoro。衣服的各向异性效果也可以很好的表现。另外,色调不同是调整的缘故

 

    中篇就到这里,后篇是,本作中使用的大气渲染和玻璃的折射表现,以及粒子表现的解说。


原作者:西川善司

原链接:http://www.4gamer.net/games/032/G003263/20130112002/

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论