铁匠smith
When planning The Blacksmith short film, we never really prioritized a custom skin shader high enough for it to have any realistic chance of being picked up as a task. However, we still wanted to see if there was something simple we could do to add a little extra life to the Challenger’s expressions. After a quick brainstorming, we decided to have a go at adding blendshape-driven wrinkle maps to the project.
在计划《铁匠》短片时,我们从来没有真正将定制的皮肤着色器的优先级设置得足够高,以至于它没有任何现实的机会被当作一项任务。 但是,我们仍然想看看是否可以做一些简单的事情来为挑战者的表情增添些生气。 经过快速的头脑风暴,我们决定尝试向该项目添加blendshape驱动的皱纹贴图。
To add detail and depth to the expressions, we decided that the Standard shader would give us the best bang for our bucks if we let the wrinkles affect both normals and occlusion. We also wanted a method of restricting the influence of certain expressions to specific parts of the face.
为了增加表情的细节和深度,我们认为如果让皱纹同时影响法线和遮挡,则标准着色器将为我们的雄鹿提供最佳的爆炸效果。 我们还需要一种将某些表情的影响限制在面部特定部位的方法。
输入皱纹贴图驱动程序 (Enter Wrinkle Maps Driver)
We created a component that allowed the animator to define the wrinkle layers, one layer per blendshape in the mesh. The layer definitions contained texture mappings and strength modifiers, as well as a set of masking weights that would be matched against a face part masking texture. Using the masking weights, specific wrinkle layers could affect one-to-four of the masked face parts, each with a different influence.
我们创建了一个组件,该组件允许动画师定义皱纹层,即网格中每个混合形状的一层。 图层定义包含纹理映射和强度修改器,以及与面部蒙版纹理匹配的一组蒙版权重。 使用遮盖权重,特定的皱纹层可能会影响到被遮盖的脸部部位的1-4分,每个部位都有不同的影响。
Since we wanted to be able to blend up to four different expressions at any given time, the blending alone required 11 texture samplers with all bells and whistles enabled (two base textures, eight detail textures and one masking texture). The only realistic option for this was to compose the blended wrinkle maps in an off-screen pre-render pass. We found that the ARGB2101010 render texture format was perfect for us, as it would allow us to pack normals into two of the 10-bit channels, with the remaining one receiving the occlusion. Each frame, the wrinkle map component would find the four most influential blendshapes, and assign layer rendering weights accordingly.
由于我们希望能够在任何给定时间混合多达四个不同的表达式,因此仅混合就需要11个纹理采样器,并且启用了所有的钟声和口哨声(两个基本纹理,八个细节纹理和一个遮罩纹理)。 唯一可行的选择是在屏幕外的预渲染通道中合成混合的皱纹贴图。 我们发现ARGB2101010渲染纹理格式对我们来说是完美的,因为它可以让我们将法线打包到10位通道中的两个中,其余的则接收遮挡。 在每一帧中,皱纹贴图组件将找到四个最具影响力的混合形状,并相应地分配图层渲染权重。
Once we had all the wrinkle data composed in screen-space, the only remaining thing to do was to redirect the normal and occlusion data inputs in the Standard shader we were using for face rendering. In practice, this just meant adding a handful of lines to the surface shader main function.
一旦我们在屏幕空间中组合了所有皱纹数据,剩下要做的就是重定向用于面部渲染的“标准”着色器中的法线和遮挡数据输入。 实际上,这仅意味着在表面着色器的主要功能中添加了几行。
// 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
// 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
最终结果 (Final Results)
Comparing the base head to the – exaggerated – angry blendshape at full weight illustrates the additional detail added in by the blended wrinkle maps:
在全权下将基部头部与–夸张–愤怒的混合形状进行比较,说明了混合的皱纹贴图增加了其他细节:
We also added various debug output modes that allowed us to easily visualize the fully blended occlusion and normal maps. These were quite useful in figuring out exactly which component contributed to what in the final result.
我们还添加了各种调试输出模式,使我们可以轻松地可视化完全混合的遮挡图和法线贴图。 这些对于准确地确定最终结果中哪个成分起作用非常有用。
旋转一下 (Take it for a spin)
We’ve broken this feature out into an example project which you can get from the Asset Store. It’s basically just the Challenger’s head with a couple of the expressions we used in The Blacksmith, but should serve as a useful starting point for getting this system running in your own projects.
我们已经将此功能分解为示例项目,您可以从Asset Store中获得该项目。 基本上,这只是挑战者的脑袋,上面有我们在《铁匠》中使用的几个表达,但是应该作为使该系统在自己的项目中运行的有用起点。
翻译自: https://blogs.unity3d.com/2015/05/28/wrinkle-maps-in-the-blacksmith/
铁匠smith