Skip to content

fix(materials): apply specular factor/color when map is present#8742

Merged
mvaligursky merged 1 commit into
mainfrom
mv-fix-specular-factor
May 18, 2026
Merged

fix(materials): apply specular factor/color when map is present#8742
mvaligursky merged 1 commit into
mainfrom
mv-fix-specular-factor

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Fixed #8735.

The glTF KHR_materials_specular specularFactor (and specularColorFactor) were silently dropped from the shader when their corresponding texture was set on the same material, producing renders that didn't match the spec or other engines (three.js, Babylon, Khronos sample viewer).

Root cause

StandardMaterialOptionsBuilder only emitted STD_SPECULAR_CONSTANT / STD_SPECULARITYFACTOR_CONSTANT when the corresponding map was absent, unless the user explicitly set specularTint / specularityFactorTint. The glTF parser sets material.specularTint = true (which masked the color-factor case in practice), but not material.specularityFactorTint, so the scalar specularFactor was silently dropped whenever specularTexture was present.

Fix

Auto-include the constant whenever its value differs from the multiplicative identity (white for color, 1 for the scalar factor), mirroring how metalness is already handled in the same file. The public specularTint / specularityFactorTint flags remain as explicit overrides.

Changes:

  • standard-material-options-builder.js: gate specularTint / specularityFactorTint on the value differing from identity, not on map absence.
  • standard-material.js: match the gating in the uniform-upload path; update JSDoc on the two flags to describe the new auto-behaviour.
  • Add a hidden test example `test/specular` that loads the Khronos SpecularTest grid as visual regression coverage.

API Changes:

  • `StandardMaterial.specularTint` and `StandardMaterial.specularityFactorTint` remain public boolean flags, but are now effectively redundant overrides: the constant is auto-applied whenever it isn't the identity value. Setting them to `true` explicitly still works. JSDoc updated to reflect this.

Examples:

  • New `examples/src/examples/test/specular.example.mjs` (hidden in production) loading the Khronos `SpecularTest.glb` grid for visual verification of `KHR_materials_specular`.

The glTF KHR_materials_specular `specularFactor` (and `specularColorFactor`)
were silently dropped from the shader when their corresponding texture was
set on the same material. Auto-include the constant whenever its value
differs from the multiplicative identity (white / 1), mirroring how
metalness is already handled. The public `specularTint` /
`specularityFactorTint` flags remain as explicit overrides.

Fixed #8735.
@mvaligursky mvaligursky self-assigned this May 18, 2026
@mvaligursky mvaligursky added the area: graphics Graphics related issue label May 18, 2026
@mvaligursky mvaligursky merged commit dd20157 into main May 18, 2026
8 checks passed
@mvaligursky mvaligursky deleted the mv-fix-specular-factor branch May 18, 2026 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: graphics Graphics related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

glTF KHR_materials_specular specularFactor behavior is not compliant with specification

1 participant