Skip to content

Blinn-Phong Fallback is Not glTF Compliant #8296

@willeastcott

Description

@willeastcott

When LIT_GGX_SPECULAR is not enabled, PlayCanvas falls back to Blinn-Phong specular, which is not compliant with the glTF 2.0 PBR specification.

Current Behavior

From litForwardPostCode.js:

#ifdef LIT_SPECULAR
    #ifdef LIT_LIGHTING
        #ifdef LIT_GGX_SPECULAR
            #include "lightSpecularAnisoGGXPS"
        #else
            #include "lightSpecularBlinnPS"  // <-- Non-glTF fallback
        #endif
    #endif
#endif

The Blinn-Phong implementation:

// lightSpecularBlinn.js
float calcLightSpecular(float gloss, vec3 worldNormal, vec3 h) {
    float nh = max(dot(h, worldNormal), 0.0);
    float specPow = exp2(gloss * 11.0);
    return pow(nh, specPow) * (specPow + 2.0) / 8.0;
}

Problem

  • Blinn-Phong produces visually different results from GGX
  • Materials authored for glTF will look incorrect when GGX is disabled
  • No roughness-based response curve matching glTF expectations
  • The highlight shape and falloff characteristics differ significantly

Visual Comparison

Aspect GGX (glTF) Blinn-Phong
Highlight shape Long tail, soft falloff Sharp cutoff
Roughness response Perceptually linear Exponential
Energy conservation Built-in Requires normalization
Physical basis Microfacet theory Empirical

Suggested Solutions

Option A: Always use GGX for PBR materials

Remove the Blinn-Phong path entirely for standard materials. Keep Blinn-Phong only for legacy/custom materials that explicitly request it.

Option B: Make GGX the default

Change enableGGXSpecular to default to true for StandardMaterial. Deprecate the Blinn-Phong path with a console warning.

Option C: Rename for clarity

Rename enableGGXSpecular to something like useLegacyBlinnPhong (inverted logic). Make GGX the implicit default, requiring explicit opt-in for legacy behavior.

Recommended Approach

Option B is recommended as it:

  • Maintains backward compatibility
  • Guides users toward correct behavior
  • Allows deprecation over time
// In StandardMaterial constructor
this.enableGGXSpecular = true; // Changed from false

// Add deprecation warning
if (options.enableGGXSpecular === false) {
    Debug.warnOnce('Blinn-Phong specular is deprecated. Use GGX for glTF compliance.');
}

Files Affected

  • src/scene/shader-lib/glsl/chunks/lit/frag/pass-forward/litForwardPostCode.js
  • src/scene/shader-lib/programs/lit-shader.js
  • src/scene/materials/standard-material.js

Metadata

Metadata

Assignees

Labels

area: graphicsGraphics related issuebugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions