Het artikel bespreekt Stylized GGX Shading, een methode om de visuele kenmerken van toon-shading te combineren met de voordelen van Physically Based Rendering (PBR).
De kern van deze aanpak is het modificeren van de Normal Distribution Function (NDF) binnen het GGX Cook-Torrance model. Door een SpecularSize-parameter te introduceren, kan de grootte van speculaire highlights worden beïnvloed terwijl de integratie in PBR-pipelines behouden blijft.
De auteur onderscheidt twee implementaties:
- Eenvoudige versie: Computationeel goedkoop, maar heeft een te sterke impact op materialen met een hoge ruwheid.
- Verbeterde versie: Gebruikt een complexere vergelijking om de oorspronkelijke NDF-vorm bij hoge ruwheid beter te behouden.
Daarnaast worden aanvullende technieken genoemd om een gestileerde look te versterken, zoals het beperken van GI probes voor een 2D-gevoel, rim lighting, outlines en het gebruik van Kuwahara filters voor verre objecten.
Stylized GGX Shading — Toon Speculaire Highlights
De rendering-vergelijking wordt dan:
float Threshold = 0.0; // elke waarde tussen 0 en 1
vec3 Radiance = BRDF * LightIntensity * step(Threshold, dot(Normal, LightDirection));
(Diffuse Thresholding / Specular Thresholding)
Men kan echter ook de 2D- en 3D-looks willen combineren: grote, scherpe highlights bij een lage ruwheid (roughness) en zachte gradiënten bij een hoge ruwheid.
Deze aanpak voelt moderner aan dan klassieke toon-shading. Bovendien kunnen we voor het grootste deel van de shading vertrouwen op PBR (Physically Based Rendering), wat het proces eenvoudiger maakt (dichter bij energiebehoud, makkelijkere integratie in bestaande pipelines, fysisch gebaseerde materiaalkalibratie, etc.).
Ik noem deze gemengde aanpak "Stylized GGX Shading".
(Video's: Toon / Stylized GGX / GGX)
Veel games hebben geëxperimenteerd met de combinatie van PBR en toon-shading. In Zelda: Breath of the Wild gebruiken de personages bijvoorbeeld pure toon-shading, terwijl de omgevingen meer leunen op een 3D/PBR-look (al is dit niet volledig, denk aan het gras). Hierdoor springen de personages uit de achtergrond.
Een ander voorbeeld is Spellcasters Chronicles, waaraan ik heb mogen werken. Tijdens de ontwikkeling hebben we veel zaken getest, waaronder deze "Stylized GGX Shading". Uiteindelijk zijn we voor iets anders gegaan, maar het maakt nog steeds gebruik van een mix tussen 2D- en 3D-looks.
(Screenshots van Zelda: Tears of the Kingdom en Spellcasters Chronicles)
Eenvoudige versie
Het meest gebruikelijke PBR-model is het GGX Cook-Torrance microfacet-model. De onregelmatigheid van het oppervlak wordt analytisch gemodelleerd als een verzameling georiënteerde microfacetten, die worden aangestuurd door een ruwheidsparameter (roughness).
De distributie van de normalen van deze microfacetten wordt beschreven door de Normal Distribution Function (NDF). Real-time engines maken meestal gebruik van de Trowbridge-Reitz NDF, die er als volgt uitziet:
// GGX Trowbridge-Reitz NDF
float D(vec3 Normal, vec3 HalfVector, float Roughness)
{
float a = Roughness * Roughness;
float a2 = a * a;
float NdotH = max(dot(Normal, HalfVector), 0.0);
float NdotH2 = NdotH * NdotH;
float denom = NdotH2 * (a2 - 1.0) + 1.0;
return a2 / (PI * denom * denom);
}
(GGX Trowbridge-Reitz NDF bij variërende ruwheid)
Door deze vergelijking licht aan te passen, kunnen we de speculaire highlights uitbreiden:
// Stylized GGX Trowbridge-Reitz NDF
float D(vec3 Normal, vec3 HalfVector, float Roughness, float SpecularSize)
{
float a = Roughness * Roughness;
float a2 = a * a;
float NdotH = max(dot(Normal, HalfVector), 0.0);
float NdotH2 = NdotH * NdotH;
float denom = max(SpecularSize * NdotH2 * (a2 - 1.0) + 1.0, 0.0001);
return a2 / (PI * denom * denom);
}
(Stylized GGX Trowbridge-Reitz NDF bij variërende ruwheid)
Om te visualiseren wat er gebeurt, heb ik een Desmos-grafiek gemaakt:
- De x-as (abscisse) representeert het dot-product van de oppervlaktenormaal en de half-vector (
NdotH).
- De y-as (ordinaat) representeert de NDF-waarde. Een hogere waarde betekent meer gereflecteerde energie.
- De zwarte curve is de originele Trowbridge-Reitz NDF; de rode curve is de gestileerde versie.
Onze nieuwe parameter "Specular Size" stelt ons in staat om bij hogere hoeken meer energie terug te geven, terwijl de oorspronkelijke vorm van de NDF behouden blijft.
(Desmos-grafiek die de Specular Size animeert) (Resulterende highlight-vorm)
Verbeterde versie
De eenvoudige versie heeft het voordeel dat deze zeer goedkoop is (1 vermenigvuldiging en 1 max), maar het heeft te veel impact op ruwe materialen, waardoor ze overmatig helder lijken.
Hier is een iets complexere vergelijking die de oorspronkelijke NDF-vorm bij een hoge ruwheid behoudt, terwijl de highlights bij een lage ruwheid nog steeds worden uitgebreid:
// Stylized GGX Trowbridge-Reitz NDF (Verbeterd)
float D(vec3 Normal, vec3 HalfVector, float Roughness, float SpecularSize, float GGXMatching)
{
float a = Roughness * Roughness;
float a2 = a * a;
float NdotH = max(dot(Normal, HalfVector), 0.0);
float NdotH2 = NdotH * NdotH;
// De GGXMatching parameter bepaalt in hoeverre de gestileerde NDF overeenkomt met de GGX bij hoge ruwheid.
// In de praktijk werken waarden van 4 of 8 goed.
float denom = max((SpecularSize * pow(1.0 - a, GGXMatching) + 1.0) * NdotH2 * (a2 - 1.0) + 1.0, 0.0001);
return a2 / (PI * denom * denom);
}
(Verbeterde Stylized GGX Trowbridge-Reitz NDF. De laatste drie kolommen komen beter overeen met de originele GGX-energiedistributie.)
In de bijbehorende grafiek die de ruwheid animeert (waarbij de curves afvlakken bij hoge ruwheid), is het volgende te zien:
- Zwarte curve: Trowbridge-Reitz NDF.
- Rode curve: De eenvoudige gestileerde versie.
- Groene curve: De verbeterde gestileerde versie.
De verbeterde versie komt overeen met de rode curve bij hoge ruwheid, en met de zwarte curve bij lage ruwheid.
(Desmos-grafiek die de ruwheid animeert)
Demo
Hier is het uiteindelijke resultaat onder variërende ruwheid, metallic-waarden en specular size.
(Video: Stylized GGX Shading)
Aanvullende opmerkingen
Men zou kunnen vinden dat deze gestileerde GGX-look niet "toon" genoeg is. Voor Spellcasters hebben we diverse toevoegingen aan deze techniek getest:
- Snoeien van GI probes: Alleen 3 SH-coëfficiënten berekenen (globaal, omhoog en omlaag voor de lucht en grond) in plaats van de gebruikelijke 9. Dit vermindert de directionaliteit, waardoor het meer aanvoelt als handgetekende 2D-kunst. Daarnaast bespaart dit prestaties omdat er minder coëfficiënten hoeven te worden opgeslagen. Een soortgelijk idee is gebruikt in Hi-Fi Rush.
- Vereenvoudigen van verre props: Gebruik van een mix van een depth-based Kuwahara filter, mip biasing en eenvoudige fog.
- Rim lighting.
- Outlines en inlines.
En natuurlijk is er veel werk verzet in de textures en het modelleren.
Stylized GGX Shading — Toon Speculaire Highlights
De rendering-vergelijking wordt dan:
float Threshold = 0.0; // elke waarde tussen 0 en 1
vec3 Radiance = BRDF * LightIntensity * step(Threshold, dot(Normal, LightDirection));
(Diffuse Thresholding / Specular Thresholding)
Men kan echter ook de 2D- en 3D-looks willen combineren: grote, scherpe highlights bij een lage ruwheid (roughness) en zachte gradiënten bij een hoge ruwheid.
Deze aanpak voelt moderner aan dan klassieke toon-shading. Bovendien kunnen we voor het grootste deel van de shading vertrouwen op PBR (Physically Based Rendering), wat het proces eenvoudiger maakt (dichter bij energiebehoud, makkelijkere integratie in bestaande pipelines, fysisch gebaseerde materiaalkalibratie, etc.).
Ik noem deze gemengde aanpak "Stylized GGX Shading".
(Video's: Toon / Stylized GGX / GGX)
Veel games hebben geëxperimenteerd met de combinatie van PBR en toon-shading. In Zelda: Breath of the Wild gebruiken de personages bijvoorbeeld pure toon-shading, terwijl de omgevingen meer leunen op een 3D/PBR-look (al is dit niet volledig, denk aan het gras). Hierdoor springen de personages uit de achtergrond.
Een ander voorbeeld is Spellcasters Chronicles, waaraan ik heb mogen werken. Tijdens de ontwikkeling hebben we veel zaken getest, waaronder deze "Stylized GGX Shading". Uiteindelijk zijn we voor iets anders gegaan, maar het maakt nog steeds gebruik van een mix tussen 2D- en 3D-looks.
(Screenshots van Zelda: Tears of the Kingdom en Spellcasters Chronicles)
Eenvoudige versie
Het meest gebruikelijke PBR-model is het GGX Cook-Torrance microfacet-model. De onregelmatigheid van het oppervlak wordt analytisch gemodelleerd als een verzameling georiënteerde microfacetten, die worden aangestuurd door een ruwheidsparameter (roughness).
De distributie van de normalen van deze microfacetten wordt beschreven door de Normal Distribution Function (NDF). Real-time engines maken meestal gebruik van de Trowbridge-Reitz NDF, die er als volgt uitziet:
// GGX Trowbridge-Reitz NDF
float D(vec3 Normal, vec3 HalfVector, float Roughness)
{
float a = Roughness * Roughness;
float a2 = a * a;
float NdotH = max(dot(Normal, HalfVector), 0.0);
float NdotH2 = NdotH * NdotH;
float denom = NdotH2 * (a2 - 1.0) + 1.0;
return a2 / (PI * denom * denom);
}
(GGX Trowbridge-Reitz NDF bij variërende ruwheid)
Door deze vergelijking licht aan te passen, kunnen we de speculaire highlights uitbreiden:
// Stylized GGX Trowbridge-Reitz NDF
float D(vec3 Normal, vec3 HalfVector, float Roughness, float SpecularSize)
{
float a = Roughness * Roughness;
float a2 = a * a;
float NdotH = max(dot(Normal, HalfVector), 0.0);
float NdotH2 = NdotH * NdotH;
float denom = max(SpecularSize * NdotH2 * (a2 - 1.0) + 1.0, 0.0001);
return a2 / (PI * denom * denom);
}
(Stylized GGX Trowbridge-Reitz NDF bij variërende ruwheid)
Om te visualiseren wat er gebeurt, heb ik een Desmos-grafiek gemaakt:
- De x-as (abscisse) representeert het dot-product van de oppervlaktenormaal en de half-vector (
NdotH).
- De y-as (ordinaat) representeert de NDF-waarde. Een hogere waarde betekent meer gereflecteerde energie.
- De zwarte curve is de originele Trowbridge-Reitz NDF; de rode curve is de gestileerde versie.
Onze nieuwe parameter "Specular Size" stelt ons in staat om bij hogere hoeken meer energie terug te geven, terwijl de oorspronkelijke vorm van de NDF behouden blijft.
(Desmos-grafiek die de Specular Size animeert) (Resulterende highlight-vorm)
Verbeterde versie
De eenvoudige versie heeft het voordeel dat deze zeer goedkoop is (1 vermenigvuldiging en 1 max), maar het heeft te veel impact op ruwe materialen, waardoor ze overmatig helder lijken.
Hier is een iets complexere vergelijking die de oorspronkelijke NDF-vorm bij een hoge ruwheid behoudt, terwijl de highlights bij een lage ruwheid nog steeds worden uitgebreid:
// Stylized GGX Trowbridge-Reitz NDF (Verbeterd)
float D(vec3 Normal, vec3 HalfVector, float Roughness, float SpecularSize, float GGXMatching)
{
float a = Roughness * Roughness;
float a2 = a * a;
float NdotH = max(dot(Normal, HalfVector), 0.0);
float NdotH2 = NdotH * NdotH;
// De GGXMatching parameter bepaalt in hoeverre de gestileerde NDF overeenkomt met de GGX bij hoge ruwheid.
// In de praktijk werken waarden van 4 of 8 goed.
float denom = max((SpecularSize * pow(1.0 - a, GGXMatching) + 1.0) * NdotH2 * (a2 - 1.0) + 1.0, 0.0001);
return a2 / (PI * denom * denom);
}
(Verbeterde Stylized GGX Trowbridge-Reitz NDF. De laatste drie kolommen komen beter overeen met de originele GGX-energiedistributie.)
In de bijbehorende grafiek die de ruwheid animeert (waarbij de curves afvlakken bij hoge ruwheid), is het volgende te zien:
- Zwarte curve: Trowbridge-Reitz NDF.
- Rode curve: De eenvoudige gestileerde versie.
- Groene curve: De verbeterde gestileerde versie.
De verbeterde versie komt overeen met de rode curve bij hoge ruwheid, en met de zwarte curve bij lage ruwheid.
(Desmos-grafiek die de ruwheid animeert)
Demo
Hier is het uiteindelijke resultaat onder variërende ruwheid, metallic-waarden en specular size.
(Video: Stylized GGX Shading)
Aanvullende opmerkingen
Men zou kunnen vinden dat deze gestileerde GGX-look niet "toon" genoeg is. Voor Spellcasters hebben we diverse toevoegingen aan deze techniek getest:
- Snoeien van GI probes: Alleen 3 SH-coëfficiënten berekenen (globaal, omhoog en omlaag voor de lucht en grond) in plaats van de gebruikelijke 9. Dit vermindert de directionaliteit, waardoor het meer aanvoelt als handgetekende 2D-kunst. Daarnaast bespaart dit prestaties omdat er minder coëfficiënten hoeven te worden opgeslagen. Een soortgelijk idee is gebruikt in Hi-Fi Rush.
- Vereenvoudigen van verre props: Gebruik van een mix van een depth-based Kuwahara filter, mip biasing en eenvoudige fog.
- Rim lighting.
- Outlines en inlines.
En natuurlijk is er veel werk verzet in de textures en het modelleren.