铁匠smith

It was bright and sunny morning. It must have been some time last fall, when we finally got the message we had all been waiting for: a Challenger has arrived!

那是一个阳光明媚的早晨。 去年秋天一定是某个时候,当我们终于收到我们一直在等待的消息时:挑战者已经到来!

Granted, it was still an early draft; bald, clean-shaven, unskinned and without proper materials set up – but we were still excited to finally have him in the project. “Somebody puh-lease slap some materials on him and put this bad boy into the scene!”

当然,这仍然是一个初稿。 秃头,剃光,没有皮肤,没有适当的材料摆设,但我们仍然很高兴最终将他纳入项目。 “有人租给他一些东西,然后把这个坏男孩当场!”

And we did. And it was awesome. Except… something didn’t quite look right. “Uhm.. is this guy really set up to receive dynamic shadows?”. He was. But not quite the kind we were expecting.

而我们做到了。 太棒了。 除了……有些东西看起来不太正确。 “嗯..这家伙真的准备好接收动态阴影吗?”。 他是。 但不是我们所期望的那种。

Most of him didn’t actually seem to receive any shadow whatsoever, and what we did identify as shadowed was very weird and jagged looking.

实际上,他中的大多数人似乎都没有收到任何阴影,而我们确定为阴影的东西看起来很怪异和参差不齐。

问题 (The Problem)

A few quick shader hacks later, and the ugly truth revealed itself; not only was half the character missing shadows altogether; what little was there was indeed looking blocky and buggy.

后来,一些快速的着色器被黑客入侵,丑陋的事实暴露了出来。 不仅角色的一半完全消失了阴影; 几乎没有什么东西确实看起来像是块状和越野车。

‘Why was this happening?’, you might wonder at this point. After all, doesn’t Unity 5 sport this brand new and shiny soft-shadow filtering algorithm? It does, and it looks great. It so happened, though, that some of our scenes had view distances as far as 3,000 meters, and we’d decided we wanted shadows cast from and onto every single pixel in the view frustum. Now, naturally we had tweaked the cascade splits and shadow biases as best we could, and the shots generally looked really good both near the camera and far, far away.

“为什么会这样?”,此时您可能会感到奇怪。 毕竟,Unity 5是否不采用这种崭新的闪亮软阴影过滤算法? 确实如此,而且看起来很棒。 不过,碰巧的是,我们的某些场景的视距最远为3,000米,因此我们决定要从视锥中的每个像素投射阴影到每个像素上。 现在,自然而然地,我们尽可能地调整了级联分裂和阴影偏差,并且无论在相机附近还是在很远的地方,这些镜头通常看起来都非常好。

What we hadn’t really tested properly until now was adding a very detailed character, very close to the camera in such a large-scene setup. Not only did we lack the resolution to produce soft, shadowy goodness on the character; the depth bias required for the scene to look good was so large that it pushed half the character out of shadow. Turns out casting soft shadows from a tiny leather strap, onto a piece or armour 1cm away, isn’t quite the same case as having a medium sized rock cast soft, stable shadows onto the ground. Who’d have thunk, right?

到目前为止,我们还没有真正进行过正确的测试,就是在非常大的场景中添加了非常详细的角色,非常接近相机。 我们不仅缺乏在角色上产生柔和暗淡的善良的决心; 场景看起来不错所需的深度偏差太大,以致于将一半角色从阴影中移出。 原来是从一条细小的皮革表带上将柔和的阴影投射到1厘米外的一件或盔甲上,与将中等大小的岩石将柔和,稳定的阴影投射到地面上的情况不同。 谁有拳头,对不对?

So we needed a solution to this predicament. We could have moved the first cascade really, really, really close to the camera, but that would have cost us a full cascade on the scenery. It would also only have worked in the scenes where the characters were really, really, really close to the camera, which would have solved enough of our problematic shots.

因此,我们需要解决这一困境。 我们本可以将第一个级联确实,非常非常靠近相机移动,但是那样会使我们在风景上花了一个完整的级联。 它也只能在角色真的非常非常接近相机的场景中起作用,这样可以解决我们很多有问题的镜头。

解决方案 (The Solution)

Instead, we decided to apply a bit of old-school technology to the problem. “What if we just explicitly render an additional shadow map focused on the character?”. Said and done. Two hundred lines of code later, the engine was generating these for us to play with:

相反,我们决定对该问题应用一些过时的技术。 “如果我们只是显式渲染一个针对角色的阴影贴图怎么办?” 说完了。 两百行代码之后,引擎正在生成这些代码供我们使用:

At this point, we were able to generate enough data to apply pretty much any kind of fancy schmancy shadow filtering we felt like. We didn’t really have a great deal of time to spend fine tuning the best possible filtering, though, so we decided to go for a simple distance-aware sampling scheme similar to Nvidia’s PCSS[1].

在这一点上,我们能够生成足够的数据以应用几乎任何我们想要的奇特的幻影阴影过滤。 但是,我们实际上并没有太多时间花在微调最佳滤波上,因此我们决定采用类似于Nvidia PCSS [1]的简单的距离感知采样方案。

Although not present in the shots shown here, we also had an option for capturing data from shadow casters outside the character’s focus area; e.g. to still have the static world cast shadows onto these dynamic characters. Such casters were projected onto the near-plane of the shadow rendering camera, ensuring they would always have the maximum blocker-to-receiver distance in the soft-shadow filtering scheme.

尽管此处显示的镜头中没有显示,但我们还有一个选项可以从角色关注区域之外的阴影投射器捕获数据。 例如,仍然让静态世界将阴影投射到这些动态角色上。 将这些脚轮投影到阴影渲染相机的近平面上,以确保在软阴影过滤方案中,它们始终具有最大的阻止者到接收者的距离。

The only problem remaining at this point was how to integrate this nicely into the rendering pipeline. After some pondering and head-scratching, it turned out there was a very simple way to override the shadow functions used by nearly all common Unity shaders. After a few iterations, we eventually simplified it to only requiring two additional lines of code to add unique shadow support to any shader:

此时唯一剩下的问题是如何将其很好地集成到渲染管道中。 经过深思熟虑后,事实证明,有一种非常简单的方法可以覆盖几乎所有常见Unity着色器使用的阴影功能。 经过几次迭代,我们最终将其简化为仅需要两行代码即可为任何着色器添加独特的阴影支持:


#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE
#include "UniqueShadow_ShadowSample.cginc"


#pragma multi_compile _ UNIQUE_SHADOW UNIQUE_SHADOW_LIGHT_COOKIE
#include "UniqueShadow_ShadowSample.cginc"

Note that the include has to go before any other engine includes for the override to work correctly. Obviously, this is slightly misleading as we just hid the actual override complexity behind an include file, so for anyone else looking to do something similar, here’s essentially what it boils down to:

请注意,必须先将include移至其他任何引擎include才能使替代正常工作。 显然,这有点令人误解,因为我们只是将实际的替代复杂性隐藏在了一个include文件的后面,因此对于希望做类似事情的其他人,基本上可以归结为:


#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


#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

The conditions in our case are whether unique shadows are enabled, and whether we’re currently rendering a directional light or not. This second condition allows the feature to co-exist peacefully with other types of shadow casting light sources.

我们的情况是是否启用了唯一的阴影,以及当前是否正在渲染定向光。 第二个条件允许该功能与其他类型的阴影投射光源和平共处。

利润! (Profit!)

So after all this hard work, did we end up with satisfactory results? Here’s the same debug view again, this time toggling unique shadows on and off:

因此,经过所有这些艰苦的工作,我们是否最终获得了令人满意的结果? 这再次是相同的调试视图,这次打开和关闭唯一的阴影:

Old-school tech for the win!

老式技术必胜!

综上所述 (In Summary)

One aspect to keep in mind is that – like most other rendering features – adding more shadow maps to your project doesn’t come for free. The shadow maps take up additional video memory, and there’s extra draw calls required to render into them, as well as increased bandwidth usage and computation power required to use them in your shaders.

要记住的一个方面是-与大多数其他渲染功能一样-向您的项目添加更多阴影贴图并不是免费的。 阴影贴图会占用额外的视频内存,并且需要额外的绘制调用才能将其渲染到其中,以及在着色器中使用它们需要增加的带宽使用量和计算能力。

For The Blacksmith, we set the system up so that we could dynamically toggle unique shadows on and off depending on how close to the camera the actors needed to be. Thus, we only paid the extra rendering cost in the shots where the characters occupied a large portion of the screen. For a game where the player might never get very close to the camera in normal gameplay, one could imagine only enabling this feature for close-ups in selected cut-scenes.

对于《铁匠》 ,我们将系统进行设置,以便我们可以根据演员需要与相机之间的距离来动态地打开和关闭独特的阴影。 因此,我们只在角色占据屏幕很大一部分的镜头中支付了额外的渲染成本。 对于一款游戏,在正常游戏过程中,玩家可能永远不会非常靠近相机,可以想象只有在选定的过场动画中对特写镜头启用此功能。

To better demonstrate this feature in isolation, we’ve put together a small demo project which you can get from the Asset Store. There’s a very basic scene included, meant to illustrate the problem case of having fine character detail near the camera in a large outdoors environment. Even with the first cascade covering only 1% of the total shadow distance, there’s a fairly radical difference between the uniquely shadowed challenger on the left, and the cascade shadowed challenger on the right.

为了更好地单独展示此功能,我们整理了一个小型演示项目,您可以从Asset Store中获得该项目。 其中包括一个非常基本的场景,旨在说明在大型户外环境中相机附近具有精细角色细节的问题情况。 即使第一个级联仅覆盖总阴影距离的1%,左侧的唯一带阴影的挑战者与右侧的级联带阴影的挑战者之间也存在相当大的差异。

References: [1] http://developer.download.nvidia.com/shaderlibrary/docs/shadow_PCSS.pdf

参考文献:[1] http://developer.download.nvidia.com/shaderlibrary/docs/shadow_PCSS.pdf

翻译自: https://blogs.unity3d.com/2015/05/28/unique-character-shadows-in-the-blacksmith/

铁匠smith

铁匠smith_铁匠中的独特角色阴影相关推荐

  1. 铁匠smith_铁匠的制作:场景设置,阴影,照明

    铁匠smith In the previous blog posts in this series we have looked at the team that created The Blacks ...

  2. 铁匠smith_铁匠的制作:概念和艺术创作

    铁匠smith For our second blog post in this series, the team reveals some sources of inspiration behind ...

  3. 铁匠smith_铁匠的制作:动画,相机效果,音频/视频

    铁匠smith In this blog post we'll be sharing our animation pipeline, and our approach to the post effe ...

  4. 铁匠smith_铁匠的大气散射

    铁匠smith Early in the planning phase of The Blacksmith, we knew we wanted an atmospheric scattering s ...

  5. 铁匠smith_铁匠镇的皱纹地图

    铁匠smith When planning The Blacksmith short film, we never really prioritized a custom skin shader hi ...

  6. Unity3D游戏制作 移动平台上的角色阴影制作

    本文将重点介绍两种目前在移动平台上的主流阴影制作技术,同时也会简单介绍两种移动平台上相对较为高级的动态阴影生成方法. 由于目前主流使用Unity3.x在移动平台上并不支持阴影的动态生成技术,所以目前最 ...

  7. 周星驰搞笑电影中的BT角色大全(100位)

    1.吴孟达 所谓"戏骨"是指那些演戏基本已经达到戏我两忘,人戏合一之境界的演员们,有句话常来形容这样一种人,说他们"浑身上下都是戏".周星驰电影中的" ...

  8. Unity3D The Blacksmith 角色阴影技术使用心得

    这个demo放出来之后,对其中的角色阴影部分的技术十分感兴趣,我就赶紧下过来研究了一下.官方的技术博客里有对这一部分技术的介绍,链接在这里:独特的角色阴影, 其中写到只要在其他shader里添加 #p ...

  9. Tomcat应用部署:打war包、在Tomcat中注册用户角色、创建虚拟目录和域名

    #1.打war包 1)命令:jar -cvf xx.war * (备注:执行打包的前提条件:目录必须切换到打包项目的webRoot(webContent)目录下) 备注:1. c:创建新的文档v:显示 ...

最新文章

  1. 利用“哨兵”“实现双链表
  2. VS Code为什么能这么牛?
  3. 第十二届西南石油大学程序设计新生赛官方题解
  4. Java的this和super关键字详解
  5. 更改putty字体颜色
  6. python打印九九加法表_Python小脚本
  7. 带你入门SpringCloud统一配置 | SpringCloud Config
  8. solr 中文分词 mmseg4j 使用例子 ,NGramTokenizerFactory
  9. 获取内网、通过外部网站返回得到内网外部IP (C#/VB.NET)
  10. 新华三:竞奔不息,永立潮头
  11. 计算机业打字排版比赛计算机实施方案,大学“新生杯”计算机打字比赛活动策划书...
  12. 使用计算机传真,使用计算机发送和接收传真
  13. 计算机网络共享打不开,电脑系统网络和共享中心打不开怎么办
  14. Java常用对象总结
  15. MacOs 查看本地IP和Mac地址
  16. 怎么才能写好技术文档?这是我的全部经验
  17. 异常你看这一篇就行了,全程白话很好理解(完结撒花)
  18. (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  19. 北大青鸟 JQuery 制作特效 第一章 课后简答题
  20. 英语的第0 1 2 3 条件句 zero conditional sentence

热门文章

  1. Web Service (二) WSDL详解
  2. android activity的跳转动画,实现activity跳转动画的若干种方式
  3. js html css代码缩进,HTML/CSS/JS代码格式化
  4. 【DL】网络搭建及训练
  5. GPT-4最震撼我的一点
  6. php批量删除 批量操作,关于thinkPHP实现批量删除的方法
  7. mysql limit 菜鸟_MySQL之二---MySQL菜鸟入门“秘籍”
  8. idea 报错Could not find resource mybatis-config.xml
  9. java typeof___typeof__() 、 __typeof() 、 typeof()的区别
  10. python画圣诞老人_使用Python给头像加上圣诞帽或圣诞老人小图标附源码