Faltenkarten in Die Schmiede

Bei der Planung The Blacksmith haben wir einem benutzerdefinierten Skin-Shader nie eine so hohe Priorität eingeräumt, dass er eine realistische Chance gehabt hätte, als Aufgabe übernommen zu werden. Dennoch wollten wir sehen, ob es etwas Einfaches gibt, mit dem wir die Ausdrücke der Challenger ein wenig lebendiger gestalten können. Nach einem kurzen Brainstorming beschlossen wir, das Projekt um Blendshape-gesteuerte Faltenkarten zu erweitern.
Um den Gesichtsausdrücken mehr Details und Tiefe zu verleihen, haben wir uns entschieden, dass der Standard-Shader uns das beste Ergebnis liefert, wenn wir die Falten sowohl auf die Normalen als auch auf die Okklusion wirken lassen. Wir wollten auch eine Methode, um den Einfluss bestimmter Ausdrücke auf bestimmte Teile des Gesichts zu beschränken.
Faltenkarten-Treiber eingeben
Wir haben eine Komponente erstellt, mit der der Animator die Faltenebenen definieren kann, eine Ebene pro Blendshape im Mesh. Die Ebenendefinitionen enthielten Texturzuordnungen und Stärkemodifikatoren sowie eine Reihe von Maskierungsgewichten, die mit einer Maskierungstextur für Gesichtsteile abgeglichen wurden. Mit Hilfe der Maskierungsgewichte können bestimmte Faltenebenen ein bis vier der maskierten Gesichtsteile beeinflussen, und zwar jeweils mit einem anderen Einfluss.

Da wir in der Lage sein wollten, bis zu vier verschiedene Ausdrücke gleichzeitig zu überblenden, waren allein für das Überblenden 11 Textursampler mit allem Drum und Dran erforderlich (zwei Basistexturen, acht Detailtexturen und eine Maskierungstextur). Die einzige realistische Option hierfür war, die überblendeten Faltenkarten in einem Pre-Rendering-Durchgang außerhalb des Bildschirms zusammenzusetzen. Wir fanden, dass das ARGB2101010 Rendering-Texturformat perfekt für uns war, da es uns erlaubte, die Normalen in zwei der 10-Bit-Kanäle zu packen, während der verbleibende Kanal die Okklusion aufnahm. Bei jedem Bild würde die Komponente Faltenkarte die vier einflussreichsten Überblendungsformen ermitteln und die Ebenen entsprechend gewichten.

Nachdem wir alle Falten-Daten im Bildschirmraum zusammengesetzt hatten, mussten wir nur noch die Normal- und Okklusionsdaten in den Standard-Shader umleiten, den wir für das Rendering der Gesichter verwendet hatten. In der Praxis bedeutete dies lediglich das Hinzufügen einer Handvoll Zeilen zur Hauptfunktion des Surface Shaders.
// 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
#endifEndgültige Ergebnisse
Wenn Sie den Basiskopf mit der - übertriebenen - wütenden Blendshape bei vollem Gewicht vergleichen, sehen Sie die zusätzlichen Details, die durch die überblendeten Faltenkarten hinzugefügt werden:


Wir haben auch verschiedene Debug-Ausgabemodi hinzugefügt, mit denen wir die vollständig überblendeten Okklusions- und Normal-Maps leicht visualisieren können. Diese waren sehr nützlich, um genau herauszufinden, welche Komponente zu was im Endergebnis beiträgt.

Wir haben diese Funktion in ein Beispielprojekt umgewandelt, das Sie im Asset Store herunterladen können. Im Grunde ist es nur der Kopf der Challenger mit ein paar der Ausdrücke, die wir in The Blacksmith verwendet haben, aber es sollte als nützlicher Ausgangspunkt dienen, um dieses System in Ihren eigenen Projekten zum Laufen zu bringen.
