风格化 GGX 着色
Stylized GGX Shading

原始链接: https://alexandrelamure.github.io/graphics-posts/stylized-ggx-shading.html

“风格化 GGX 着色”是一种将经典卡通美学与基于物理的渲染(PBR)相结合的渲染技术。传统的卡通着色通常使用阈值处理来创建平坦的色彩渐变,而这种方法通过调整标准的 GGX Cook-Torrance 微平面模型,呈现出更现代、更灵活的视觉效果。 通过修改 Trowbridge-Reitz 法线分布函数(NDF),作者引入了一个“高光尺寸”(Specular Size)参数。这使得美术人员能够在保持粗糙表面柔和、自然渐变的同时,对光滑表面的锐利高光进行扩展。该技术提供了两种实现方式: 1. **简化版:** 一种计算成本较低的修改方案,可以扩展高光,但在处理粗糙材质时可能会导致亮度过高。 2. **改进版:** 使用额外的“GGX 匹配”参数,在保持高粗糙度下原始 NDF 形状的同时,成功实现低粗糙度高光的风格化。 这种方法可以无缝集成到现有的 PBR 工作流中,确保了能量守恒并简化了材质校准。为了进一步实现 2D 视觉效果,作者建议将此着色技术与简化全局光照(SH 系数)、基于深度的滤镜、边缘光以及描边等技术相结合,正如《Hi-Fi Rush》等游戏中所呈现的那样。

```Hacker News最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交登录风格化 GGX 着色 (alexandrelamure.github.io)7 分,由 ibobev 在 1 小时前发布 | 隐藏 | 过往 | 收藏 | 讨论帮助 考虑申请 YC 2026 年秋季批次!申请截止日期为 7 月 27 日。 准则 | 常见问题解答 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:```
相关文章

原文

Back to graphics

July 19, 2026

To achieve a toon look in 3D rendering, the most common way is to threshold the lighting. It transforms the soft color gradients into flat colors.

// The rendering equation becomes:
float Threshold = 0.0; // any value between 0 and 1
vec3 Radiance = BRDF * LightIntensity * step(Threshold, dot(Normal, LightDirection));

However, one might want to mix the 2D and 3D looks: big sharp highlights at low roughness and soft gradients at high roughness. It feels more modern than classic toon shading, and we can rely on PBR for most of our shading, making everyone's lives easier (closer to energy-conservation, easier integration into existing pipelines, physically-based material calibration...).
I call this mixed approach "Stylized GGX Shading".

Toon
Stylized GGX
GGX

Many games have explored the combination of PBR and toon shading.
For example in Zelda: Breath of the Wild, the characters use pure toon shading but the environments rely more on a 3D / PBR look (not completely, e.g. the grass). This makes the characters pop out of the background.

Another example is Spellcasters Chronicles, which I had the chance to work on. During development we tested many things, including this "Stylized GGX Shading" I'm describing here. In the end we landed on something else, but it still uses a mix of 2D and 3D looks.

Simple version

The most common PBR model is the GGX Cook-Torrance microfacet model.
The surface's asperity is analytically modeled as a collection of oriented microfacets, and controlled by a roughness parameter. The distribution of these microfacets' normals is described by the Normal Distribution Function (NDF). Real-time engines usually use the Trowbridge-Reitz NDF, which looks like this:

// 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
GGX Trowbridge-Reitz NDF, at varying roughness

By slightly modifying this equation, we can expand the specular highlights.

// 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
Stylized GGX Trowbridge-Reitz NDF, at varying roughness

I made a Desmos graph to visualize what's happening (follow the link to play with its parameters).
Abscissa represents the dot product of the surface normal and the half-vector (NdotH).
Ordinate represents the NDF value (the return value). Higher means more reflected energy.
Black curve is the original Trowbridge-Reitz NDF, red curve is the stylized one.
Our new "Specular Size" parameter allows us to return more energy at higher angles while preserving the original shape of the NDF.

Improved version

The simple version has the benefit of being extra cheap (1 mul and 1 max), but it impacts rough materials too much, making them appear overly bright.
Here is a slightly more complex equation that preserves the original NDF shape at high roughness, while still expanding the highlights at low roughness.

// Stylized GGX Trowbridge-Reitz NDF
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;
    // The GGXMatching parameter controls how much the stylized NDF matches the GGX one at high roughness. In practice, 4 or 8 works well.
    float denom = max((SpecularSize * pow(1.0 - a, GGXMatching) + 1.0) * NdotH2 * (a2 - 1.0) + 1.0, 0.0001);
    return a2 / (PI * denom * denom);
}
Improved Stylized GGX Trowbridge-Reitz NDF
Improved Stylized GGX Trowbridge-Reitz NDF.
The last three columns better match the original GGX energy distribution.

Here is the graph animating the roughness (at high roughness the curves flatten).
Black curve is the Trowbridge-Reitz NDF, red curve is the simple stylized and green curve is the improved stylized. The improved version matches the red curve at high roughness, and the black curve at low roughness.

Desmos graph animating the roughness

Demo

Here is the final look under varying roughness, metalness and specular size.

Stylized GGX Shading

Side notes

One might feel like this stylized GGX look is not "toon" enough.
On Spellcasters we tested many additions to this trick:

  • Prune the GI probes by only computing 3 SH coefficients (global, up and down for the sky and ground) instead of our usual 9 coefficients. This lets us reduce the directionality, making it feel more like hand-drawn 2D art. It also saves performance as we can store fewer coefficients. The same kind of idea has been used in Hi-Fi Rush.
  • Simplify the distant props using a mix of a depth-based Kuwahara filter, mip biasing, and simple fog.
  • Rim lighting.
  • Outlines and inlines.
  • And of course, a lot of work went into the textures and modeling.

Back to graphics

联系我们 contact @ memedata.com