📜 ⬆️ ⬇️

Wrinkle Cards in The Blacksmith Video

At the planning stage of The Blacksmith video, we never seriously considered creating a special shader for the skin. We needed a simple solution that would make the antagonist's mimic more realistic. Without thinking twice, we tried to add blend wrinkle-based wrinkle maps to the project.

We decided that it would be most profitable to simply add normal maps and shading maps to the standard shader for detailing the mimicry of the character. In addition, we had to find a way to limit the influence of emotions on the relevant parts of the face.



Wrinkle maps driver
')
We created a special component to define wrinkle layers (one layer per blend in the mesh), which included texture maps, impact modifiers, and a set of masks for applying to facial textures. In addition, each layer of wrinkles could affect different parts of the face (from one to four).



So, we needed the ability to mix up to four facial expressions at any given time. This required as many as 11 textures, including two basic textures, eight texture details, and one mask texture. Therefore, in order to avoid additional difficulties, we decided to create wrinkle cards at the pre-rendering stage. For this purpose, the ARGB2101010 format ideally suited us. Thanks to him, we managed to pack normals into two 10-bit channels, and shading - into the third channel. In each frame, our component defined the blend shampoo with the greatest influence and appropriately distributed the impact of the render layers.



When all the wrinkles were arranged in the screen space, we only need to redirect the data from the normal and shading maps to the standard shader, which we used for facial rendering. In other words, we only needed to add a few lines to the main function of the surface shader.

// Sample occlusion and normals from screen-space buffer when wrinkle maps are active
#ifdef WRINKLE_MAPS
float3 normalOcclusion =
tex2D (_NormalAndOcclusion, IN.screenPos.xy / IN.screenPos.w) .rgb;
o.Occlusion = normalOcclusion.r;
#ifdef _NORMALMAP
o.Normal.xy = normalOcclusion.gb * 2.f - 1.f;
o.Normal.z = sqrt (saturate (1.f - dot (o.Normal.xy, o.Normal.xy)));
#endif
#endif

End results

On the example of a blend shampoo with an evil expression, we can see all the smallest details that appear in the picture thanks to the wrinkle maps:




In addition, we added several debugging modes, which greatly simplified the visualization of normal and shading maps, and also allowed us to determine exactly what each component is responsible for in the final image.



Try it yourself

We have specially created a test project that can be downloaded from the Asset Store. In fact, these are just a few emotions on the example of the antagonist's face from The Blacksmith video, but they can serve as a good starting point for your projects.

Source: https://habr.com/ru/post/269187/


All Articles