我都专栏目录:
小IVan:专题概述及目录![图标](https://i-blog.csdnimg.cn/blog_migrate/d6ea8e09530a242b2ee5802be9b6a242.png)
简介:
在游戏种制作种,人物的占比越来越大而且已经成为一个体系。渲染和优化的时候都会为角色量身定制一套方案。甚至为了角色表现,把展示选择大厅的角色还单独做一套效果和资源。角色身上的材质和制作都是游戏美术资源中最复杂的。人物篇将研究角色的各个部位的各种做法。
本篇将先从最难的头发开始。分别从制作大型和Shading几方面入手。目前业内经常使用Maya的XGEN作为主要制作工具。不过这一章我使用ZBrsuh+3DMax来制作头发。
【Hair Shading】
本文使用Pekelis et al. 2015, "A Data-Driven Light Scattering Model for Hair"的Shading方案,这也是Unreal内置的HairShadingModel使用的方案。下面就来详细阐述其原理。
![v2-6b229c0e8d1a328b8089a523ddcda535_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/827894f5e89967ecf8d6de7b0411951d.jpeg)
Kajiya and Kay's HairShadingModel只是大概描述了以下头发的光照模型,再七八年前效果还能满足需求,但是现在对渲染品质要求的提高,所以业界提出了新的光照模型。如果对怎么构建光照模型和Kajiya and Kay's不熟的话,可以先去看我前面的两篇文章:
![v2-be9876a139fe8daeefcc4bb90b87b347_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/c3f43ce46a35ce5f98130a813f199ee4.jpeg)
将光路分为了三项
(1)R:由于头发纤维的倾斜,所以假设了一个偏差,将高光朝着发根的方向偏移,头发的各向异性高光。
(2)TT:头发的强烈散射部分,当光从头发背面打过来的时候,会产生强烈的透光散射就是这项计算的。
(3)TRT:在头发内部光线再次反射出来的光线,头发的次级高光点。
这个光照模型已经考虑得非常完善了,当然如果你还嫌不够的话还可以自己对光线进行建模,比如R摄入之后在头发介质中的传播还可以考虑多次散射。Data-Driven Light Scattering Model for Hair对上述三项进行了改进,重要性采样等,效率更高效果更好。
![v2-fb881f055141052c014771d057e0e93e_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/4ddf905b3a1aa27352c1a1fc06296a8a.jpeg)
...........................................(1)
.......................................(2)
【Hair Assets Production】
首先需要准备头发的模型。头发的做法根据建模的方式目前可以分为两种,一种是几何体形状的,一种是插片的。如果大量使用集合体状的来制作模型,一般是卡通项目。大量选用面片的话一般是写实类,但是写实类也会有使用几何模型来制作头发某些部分的情况。本篇是制作写实类的。下面是我在ZBrush中制作的头发基础模型。
![v2-43bb53d1917b3f2f7c2bb631cf8b6ba6_b.gif](https://i-blog.csdnimg.cn/blog_migrate/2512d21aac1138bc2d05d34c8dcbfd38.gif)
MeshFilter可以非常方便地制作头发的模型的大型,具体细节可以导回Max或者Maya中再做调整。不管用什么工具来制作,这个工具只要满足以下几个条件就可以使用这个工具来制作。
(1)方便制作大型,调整大型,各种发型,包括但不限于卷发,各种鞭子。
(2)能方便分UV,人工分这么复杂头发模型的UV实在不是个好注意。
(3)能够从高模烘焙出各种基础资源,如BaseColor,Tangent,Normal,ID,Depth等信息。
(4)头发面片穿插较少,层于层之间的间隔要固定,下图红圈部分的头发刚好侧面对着摄像机所以可以看到这一特性。
![v2-e5dc8be3bbd679187eeb3b8353dea81b_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e9bbb686e82d977997d986f3fddccd9c.jpeg)
在导出模型之前,把FiterMesh使用FiterMeshUV。
![v2-b6f0b7560f8f7b9f06ee86a3426b413f_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/b64b7f13397ca1293bb67c5b2ef76b0b.jpeg)
因为我的模型已经Create过了所以这里是Disable的状态。导入到max可以看到如下效果:
![v2-e0f015cda97f99809e3c0ec5ea249c59_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/5d397469104abccb4aa9c365488512a8.jpeg)
UV被分得工工整整的,但是所有UV都是重叠的。
![v2-95f2900fe6b7b19cdc2050b9a541347a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/ba7e6edb9a7d20da80e6231524c0e4cb.jpeg)
这正是我们想要的效果。准备好模型后就可以进入下一步了。我把头发分为长发部分,发梢部分,刘海部分,耳发部分,不同的模型会有不同的头发类型。下面就来制作头发的贴图。具体贴图怎么制作需要根据头发的Shader是如何写的来决定。
因为我们需要发丝的法线,Tangent,深度,Opacity等信息,所以我们需要制作头发的高模
![v2-7951a1ca1c16f4e121cad9da6831ae9d_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/b409ff70332df2a725d327dd6f16624f.jpeg)
高模也可以用FiterMesh制作或者使用XGEN。然后架一个平面,把我们需要的信息从高模上烘焙到贴图上。
【Hair Shading in unreal engine 4】
把Opacity和Normal还有Base_Color导入引擎,设置好材质后可以看到如下效果:
![v2-d06f835b61891379aa1c20a0b716ae0e_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/96a0f7507b9677f4fe372e67d4d1446a.jpeg)
可以看到有很多问题。第一:因为目前所有头发使用了一个头发高模烘焙出来的发丝Opacity,所以变化比较单一,耳发。刘海都。第二:因为没有制作Tangent贴图所以各向异性高光计算错误。第三:没有深度偏移,所以头发没有层次感。下面就先从这三个问题切入。
【1】因为这是使用的面片,所以使用顶点自己本身的切线也可以大概描述发丝的走向,这样便可以计算R和TRT项了效果如下:
![v2-51eb2a947b1f5fb526907a696e38fa35_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/1dfbac234273c22dc37803d0cc50f4ba.jpeg)
可是使用顶点的tangent并不精确,可以看到上图的高光是乱的。顶点Tangent如下图所示:
![v2-a7196f6fd7f2bd707abc7d5f886624c1_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/b08c12aff98e42e198aeea705395dbf8.jpeg)
如果头发模型的段数够高,或者角色是短发,可以跳过这个问题。如果不想使用头发自己的vertex tangent可以制作FlowMap,这道工序我会在后面提到。
【2】为了头发更自然,我多制作了几套头发片的高模。
![v2-b99bff698b5873c3c2af031c3e1a2551_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/c2dda3f9e642deb64ef32cecbbddf7c7.jpeg)
因为FiterMesh分出来的模型一开始UV都是重叠的,所以我们可以选中整片头发然后SplitUV然后慢慢调整。给头发的各个部分做区分后,可以得到如下效果:
![v2-2a0a9f3e5e97c367bbc06cee9bb48a49_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/30def83a72ede1a957ee60950394d836.jpeg)
虽然头发变化增多了,但是头发整体还是感觉哪里很奇怪,这就要说到上一个话题,因为使用的是Vertex的Tangent,所以每个头发面片都是像鳞片一样镶嵌在头上的,不是一个整体。
下一步是把UV平展然后分出第二套UV
![v2-ea4d770acc1b57ce92447881808d3233_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/7deebdea319eb9264d73ab37f801c6e5.jpeg)
可以在二套UV上制作FlowMap和Depthmap。Depthmap用于做PixleOffset。下面我使用SubstancePainter制作FlowMap
在SP中制作flowmap第一步创建一张(128 0 255) 的FlowBaseMap
然后对笔刷做如下设置:
![v2-25edc8fe1d098c761055476002bac82b_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/34a3ee5ae3f24e1d23445cc0ab5b52bc.jpeg)
便可以绘制flowmap了
![v2-ad2561dabb3a8ea85a317360bc3a7c9d_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/08e4cf08f4b168c7fab7de0306985a77.jpeg)
![v2-aae12d9d44d57fd6a4f15b6c6ef3101a_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/e42dcbc73f4c55600042d1c6fd9dd12a.jpeg)
FlowMap可以讲头发面片整体化,可以看到不同面片的高光点位置连续了,如下图所示:
![v2-4018de0105ccc4f21d57e28176ce3a95_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/7a150bf94c51d61240da326621aac1ab.jpeg)
![v2-65e4f8e8bfd6929fd6c1a0ff3bb5db2d_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/50a572715f0bbe5e5933979431a2f8c6.jpeg)
和只使用顶点tangent的效果比起来,后脑勺部分的长头发高光效果改善显著。
【3】现在来解决第三个问题,层次感。发丝是有层次的,但是我们的模型是面片,也就是说面片模型会导致大片大片的发丝深度是一样的。
![v2-c3c971479b6d209e86f0b262af88756c_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/68bb260a25d77e3be792a23f17330708.jpeg)
模型发丝深度如左图所示,正确的发丝深度如右图所示。所以我们需要深度图。对于深度图其实还有很多作用,如果使用AlphaBlend来做头发的话深度还能防止透明乱序。
AlphaTest + TAA Dither Alpha 不需要考虑乱序的问题。
除了深度以外,还需要IDMap和RootMap。在开始制作深度图之前,需要先了解清楚DepthOffset的作用原理。把两个面片重叠在一起,可以看到如下效果:
![v2-63b43590339abb09e138e1774f54528e_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/f5837893896ba4c625b404b65b5e76ca.jpeg)
这就是常说的ZFighting,可以通过修改PixleDepth来对当前像素做深度偏移。
![v2-73b450941e5419d7022e2d5200a026ad_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/113b4044cb21a3ca2e08b968e4c01e14.jpeg)
用这种方法就可以对头发面片上的发丝做偏移了,这样可以制作出层次感和避免乱序。
如果不做偏移,同一个面片上的发丝始终是没有层次感的。
![v2-91aedb631962d42332a8aa697bcb7d46_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/5a2d1aa7d0804d2ad61274e2cd6c541e.jpeg)
不过在烘焙深度和ID之前我们需要吧模型的Modeling做完。之前只是做了头发的基础,我们还需要完成头发的一些小的发丝。和制作头发基础模型一样,还是在zb中制作。发丝模型不必太多,只是零星点缀在头发模型表面。
![v2-9ef66dc13701d5881a937d712465ce03_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/2e464344ac00c8ef7e55089d7346bed1.jpeg)
然后为其准备一个高模然后烘焙其Alpha
![v2-c921a27e672317953e58f16206b9f1df_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/3178c213b3d1d1eec3e170c8cd6e418a.jpeg)
把它加到原来的模型上,效果如下:
![v2-d6c22aff3b1f08750cc939f232d5522d_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/848c0eaedd44a2d655febfb47414b605.jpeg)
完成了最后的Modeling,那么就开始烘焙ID和深度来解决最后的头发面片本身无层次感的问题:
![v2-65dff32f2860455c512642635bfdf30e_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/b9da9bd39be8856b27a93c5a25f899f8.jpeg)
加入ID和深度后,头发的层次感增强。
![v2-a2849be7a87e945478950434821959e5_b.jpg](https://i-blog.csdnimg.cn/blog_migrate/27fe66ac74a01711fbca5ccfadc6b2db.jpeg)
Conclusion:
头发制作之前需要根据具体的Shading方案来定制资源生产流程。就拿Data-Driven Light Scattering Model for Hair来说,主要需要提供IDTexture,AlphaMap,MetallicTexture,RouphnessTexture,DepthTexture,AOTexture,TangentTexture,BaseColorTexture
上面我使用的ZBrush+3DMax+SubstancePianter的制作流程的主要问题是制作头发高模的时候无法制作较好的BaseColorTexture和AphaTexture。DepthTexture效果也不令人满意。
下一节将完善这个流程。
Enjoy it !
参考文献:
【1】https://graphics.pixar.com/library/DataDrivenHairScattering/paper.pdf
【2】http://graphics.stanford.edu/papers/hair/hair-sg03final.pdf