BLACKSMITH深度分享系列
相信此在Unite上的惊艳亮相,让许多人至今无法忘却它所带来的震撼,Unity的大师们为了让更多Unity开发者了解此是如何用Unity5诞生的,深度分享了多篇技术干货,从各个维度详解BLACKSMITH的创作过程。

继上篇为各位介绍了BLACKSMITH的项目中的大气散射,本次将为各位介绍:BLACKSMITH深度分享之独特的角色阴影。
那是在一个阳光明媚的早上。我想应该是去年秋天的某个时候,我们终于等到了翘首期盼的消息:维京挑战者!终于来临!
当然,它仍是一个早期的草稿:一個光头、没有任何皮肤紋理也尚未赋予任何材质——但我们依然为他来到我们的项目中而感到兴奋。 “快来人啊,把给这坏小子给我打上材质,然后丢进我们的场景吧!”
我们就真的这么干了。而且它确实看起来非常炫酷。除了……有些地方看起来怪怪的。“呃,这家伙真的有接收动态阴影吗?”。事实上他真的有接收动态阴影,然而并非以我们所期望的方式。
152932baa1zmrr6rp11rt8.jpg

他总体上看来并没有收到任何影子,因此我们也断定问题就出在阴影上,它看起来很奇怪,而且参差不齐。
问题所在
我们快速的对着色器(shader)进行了研究之后,丑陋的已原形毕露:不仅是一半的角色完全丢失了阴影,更别提这角色阴影看起來有种块狀的诡异感。
152930hmf60udkxx8d5pux.jpg

“为什么会这样呢?”,你可能因此而感到好奇。Unity5不是采用了全新的闪闪的软阴影过滤算法么?确实如此,而且的确很強大。说来也巧,但是,我们的一些场景最远有3000米的距离,而且我们已经决定,希望从那么远投射阴影,到视维的每一个像素上。现在,我们自然就竭尽所能地调整了级联和阴影偏移,无论是近距离还是离镜头非常非常远,效果看起来都很不错。
然而,到目前为止,我们却从未经历过这样一种情况,那就是在一个如此宏大的场景中添加一个离相机很近卻又具有诸多细节的角色。我们不仅缺乏用于在角色身上产生软阴影的分辨率,为确保场景美观所需要的深度偏移是如此之大,以至于它将角色一半的身体推出了阴影。原来,一块皮带在距离它1cm的盔甲上投射出软阴影,和一块中等尺寸的岩石在地面上投射出软阴影的情况并不完全相同。又有谁能料到呢,嗯?
因此我们需要寻求一个解决方案来解決这困境。我们可以将Quality Setting里阴影级联(Shadow Cascades)的第一级移动到非常非常靠近相机的位置,但代价就是这场景浪費了一级可用。它仅仅会在我们的角色们真的非常非常靠近相机时才会运作,虽然这已经足够解决我们眼下遇到的这个问题了。
解决方案
然而,我们决定用一种比较老派的技术解決于这个问题。“如果我们仅仅针对角色另外渲染一个额外的阴影贴图呢?”说到做到。两百行代码之后,游戏引擎为我们展示了这样的画面:
152931x90h6bf54v64y250.jpg

此时,我们已经能够产生足够多的数据来呈现任何能够想到的华丽绝伦的阴影过滤了。虽然如此,我们并没有大量的时间去对最佳过滤进行微调,我们决定去做一个类似于Nvidia光导开关[1]的一个简单的距离感知采样方案。
虽然没有出现在这些展示的截图中,我们还设有一个选项用于捕捉人物对焦领域之外的阴影投射数据的选项;比如说,我们仍然需要有静态的世界的阴影透射到这些动态的角色上。这类投影被会被投到阴影渲染镜头最面上,以确保他们在软阴影滤波方案中总是具有最大的拦截-接收距离 。
如此一来,剩余的唯一的问题便是如何将上述工作集成到渲染管线了。在一些抓耳挠腮的琢磨之后,结果我们发现原来有一个非常简单的方法来对常见的Unity shader所用的阴影方法进行重写。经过几次反复,我们最终将其简化为只需添加两行额外的代码就可以对任意着色器添加这种独特的阴影支持:
[C] 纯文本查看 复制代码#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE #include UniqueShadow_ShadowSample.cginc
请注意,为确保这种重写能够正常运作,这里的“include”部分必须写在其他的engine includes之前。显然,这里可能存在一些轻微的误导,因为我们在这里用了一个include文件来将真正的复杂部分给覆盖了。若有人想要做类似的事情,这里本质上可以归结为:
[C] 纯文本查看 复制代码#if SOME_CONDITION_ENABLING_OUR_FEATURE #include AutoLight.cginc #undef SHADOW_COORDS #undef TRANSFER_SHADOW #undef SHADOW_ATTENUATION #define SHADOW_COORDS(i) SOME_OTHER_COORD(i) #define TRANSFER_SHADOW SOME_OTHER_TRANSFER #define SHADOW_ATTENUATION(i) SOME_OTHER_ATTEN(i) #endif
这里的条件判断决定了是否启用这种独特的阴影,以及我们目前是否正在呈现一个定向光。而第二个条件判断则决定了能否与其他类型的投影光源和平共处。
福利 在经历了所有艰苦困苦的工作之后,我们究竟获得了怎样的令人满意的结果呢?下面就是同一个调试场景在打开和关闭这种“独特阴影”技术时,所呈现出来的场面。老派技术最终得分获胜!
152932lx8er5w85g01rxgp.jpg

154122yhtt80744te090p0.png

锐亚教育

锐亚教育 锐亚科技 unity unity教程