Skip to content

Add conformance assets for coat, fuzz and diffuse_roughness - #288

Open
dfattal wants to merge 1 commit into
KhronosGroup:mainfrom
DisplayXR:add-openpbr-conformance-sweeps
Open

Add conformance assets for coat, fuzz and diffuse_roughness#288
dfattal wants to merge 1 commit into
KhronosGroup:mainfrom
DisplayXR:add-openpbr-conformance-sweeps

Conversation

@dfattal

@dfattal dfattal commented Aug 18, 2026

Copy link
Copy Markdown

Parameter sweeps for three of the in-progress OpenPBR-alignment extensions. @MiiBond confirmed on #2534 that conformance assets do not exist for coat, fuzz or diffuse_roughness, and that conformance assets are more useful than demo ones at this stage — these are meant as the former.

We implemented all three in our glTF viewer and fed the findings back onto the extension PRs (#2534, #2538, #2481); these assets are what we built to test against.

What is here

Model Extension Rows
CoatParameterSweep KHR_materials_coat 7 x 8
FuzzParameterSweep KHR_materials_fuzz 4 x 8
DiffuseRoughnessParameterSweep KHR_materials_diffuse_roughness 3 x 8

Each row varies exactly one property, so a difference between two implementations localises to a single parameter rather than to "the material looks wrong". Each asset leads with a control row built for direct comparison:

Coat pairs KHR_materials_clearcoat against the KHR_materials_coat material the conversion table says it maps to — four matched pairs, adjacent in one row. Sharing a row means sharing a height and therefore an environment, which is what makes "these must render identically" exact rather than approximate. An earlier version placed the control in a separate row, and under a vertically varying environment two identical mirror-ish materials at different heights simply do not match, so the comparison quietly stopped being a test. coatDarkeningFactor is pinned to 0.0 on the coat halves, since clearcoat never modelled internal-reflection darkening and the pair could not otherwise match; row 3 sweeps darkening on its own.

Fuzz carries a KHR_materials_sheen reference row sweeping the same colour range as the fuzz row. These are expected to diverge: a black sheen colour disables that layer entirely, while fuzz keeps an independent weight and goes sooty instead of vanishing. An implementation rendering the two rows alike has likely routed fuzz through its sheen path.

Diffuse roughness places "extension absent" next to diffuseRoughnessFactor 1.0 as touching neighbours, at four base albedos. The effect is small enough that a gradient across eight spheres is unreadable, so the endpoints sit side by side instead. Measured deltas are tabulated in that model's README.

Notes for reviewers

The assets are generated by a script rather than modelled, so they can be regenerated cheaply if a draft extension changes.

CoatParameterSweep reports UNUSED_MESH_TANGENT and UNUSED_OBJECT infos. These are false positives and the attributes should not be stripped — the validator has no KHR_materials_coat support, so it cannot see row 6 sampling coatNormalTexture, and row 5's coatAnisotropyStrength requires a tangent space per the extension. Both other assets are down to a single UNSUPPORTED_EXTENSION info. All three are 0 errors, 0 warnings across both variants.

One limitation worth stating, since it affects how much any single number here should be trusted: for diffuse_roughness the normative behaviour is the direct-light BRDF, while IBL handling is explicitly left to the implementation. A renderer whose lighting is environment-dominated is therefore exercising implementation-defined behaviour more than specified behaviour, and two conforming renderers may legitimately differ on those spheres by more than they would on a direct-lit scene.

Happy to adjust naming, tags, framing or the row layouts to whatever suits the repo — and to add assets for KHR_materials_scatter alongside #269 if that would be useful.

Parameter sweeps for three of the in-progress OpenPBR-alignment extensions,
which currently have no conformance assets. Each row varies exactly one
property, so a difference between two implementations localises to a single
parameter rather than to "the material looks wrong".

Each asset leads with a control row built for direct comparison:

* CoatParameterSweep pairs KHR_materials_clearcoat against the
  KHR_materials_coat material the conversion table says it maps to, four
  matched pairs adjacent in a single row. Sharing a row means sharing a height
  and therefore an environment, which is what makes "these must render
  identically" exact rather than approximate. coatDarkeningFactor is pinned to
  0.0 on the coat halves, since clearcoat never modelled internal-reflection
  darkening and the pair could not otherwise match.

* FuzzParameterSweep carries a KHR_materials_sheen reference row sweeping the
  same colour range as the fuzz row. These are expected to diverge: a black
  sheen colour disables that layer entirely, while fuzz keeps an independent
  weight and goes sooty instead of vanishing.

* DiffuseRoughnessParameterSweep places "extension absent" next to
  diffuseRoughnessFactor 1.0 as touching neighbours, at four base albedos.
  The effect is small enough that a gradient across eight spheres is unreadable,
  so the endpoints are put side by side instead. Measured deltas are in that
  model's README.

The assets are generated by a script rather than modelled, so they can be
regenerated cheaply if a draft extension changes.

Two notes for reviewers:

The glTF-Validator reports UNUSED_MESH_TANGENT and UNUSED_OBJECT against
CoatParameterSweep. Those are false positives and the attributes should not be
stripped: the validator has no KHR_materials_coat support, so it cannot see row
6 sampling coatNormalTexture, and row 5's coatAnisotropyStrength requires a
tangent space per the extension. All three assets are otherwise clean, 0 errors
and 0 warnings across both variants.

For diffuse_roughness specifically, the normative behaviour is the direct-light
BRDF while IBL handling is left to the implementation, so results under an
environment-dominated renderer are implementation-defined to a degree worth
knowing before treating any single number as a pass or fail.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PBR Physically Based Rendering

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants