Shadows of characters in the Blacksmith movie

Original author: Torbjorn Laedre
  • Transfer
One beautiful morning last fall, we learned the long-awaited news: the antagonist is ready!
It was just a draft model: without hair, skin, and the corresponding adjustment of materials, but we were still very happy. Someone immediately suggested: “Let's quickly stick materials on him! I’m eager to see this guy on the screen! ”

So we did. But something went wrong ... "Wait, did we fine-tune it to get dynamic shadows?" That's right. But the result did not meet our expectations at all.



Problem

Having rummaged around in the shader, we discovered the essence of the problem: half the shadows did not display in principle, and the second half did not display correctly.



“What's the matter?” You ask. “What is the new filtering algorithm in Unity 5 that makes shadows softer and more realistic?” But the fact is that in some scenes the camera was at a distance of up to 3000 meters, and we wanted the shadows to be displayed on each pixel within its field of view. Of course, we specially configured cascading splits and offset parameters for high-quality display of shadows both directly in front of the camera and at a great distance.

The problem is that we did not foresee a close-up of the character in such a large-scale scene. Not only did we lack permission to create soft shadows, but the depth offset that we set for the scene was so large that the character was practically left without shadows. It turns out that the soft shadow cast by a leather strap on the armor is very different from the soft shadow cast by a large cobblestone on the ground. Who would have thought!

So, we needed to find a solution to this problem. We could bring the first cascade as close as possible to the camera, but then we would have to sacrifice a common cascade for the whole shot. Such an option would be suitable exclusively for scenes with a very close-up, which, in principle, was required.

Decision

Nevertheless, we decided to apply a more traditional technology: make separate shadow cards for the characters. Two hundred lines of code - and voila! Here's what we got:



At this stage, we already had enough data to apply almost any shadow filter. But there wasn’t enough time to fine-tune it, so we decided to focus on simple sampling taking into account the distance, similar to the Nvidia PCSS shadow technology [1].

In addition, we have the opportunity to collect data from static objects that are outside the close-up and casting shadows on dynamic objects, that is, on characters. Static objects were projected onto the front plane of the rendering camera, which ensured the maximum Blocker-to-Receiver distance in the soft shadow filtering scheme.

It remains only to integrate our solution into the overall pipeline rendering. Having broken our minds a bit on this issue, we found a very simple way to replace the shadow functions used in almost all standard Unity shaders. After several iterations, we simplified it to two lines of code: Note that for this function to work correctly, the #include line must be written before any other #include lines in the code. If you plan to use this method for similar purposes, keep in mind that the complexity of the replacement lies in the code hidden in the include file: In this case, we have 2 conditions: whether support for unique shadows is enabled and whether the source of the directional light is rendered. The second condition allows you to combine this function with other light sources that cast shadows.

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




#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




Result

So, have we managed to achieve satisfactory results? See for yourself! This is how the same render looks with unique shadows and without them:



Conclusion

Do not forget that additional shadow maps, like any other rendering functions, require additional resources. They take up more video memory, use more rendering calls when rendering, and also require more channel load and processing power for use in the shader.

For the Blacksmith video, we specifically added the ability to turn on and off unique shadows, depending on how far the characters are from the camera. Thus, the load on the system increased only during the rendering of close-up shots. In games where the camera’s proximity to the player is not provided in principle, this function can only be added for individual close-ups in screensavers.

To better demonstrate this feature, we created a small demo project that can be downloaded on the Asset Store.On the example of a scene from the video, you can see how to maintain high detail close-up of the character in a large open space. Despite the fact that the first cascade covers only 1% of the total Shadow Distance, the difference is obvious: a model with unique shadows on the left looks much better than a model with cascading shadows on the right.



Reference .

Also popular now: