Skip to content

Adding KHR_materials_retroreflection example - #285

Open
mklefrancois wants to merge 5 commits into
KhronosGroup:mainfrom
mklefrancois:khr-materials-retroreflection
Open

Adding KHR_materials_retroreflection example#285
mklefrancois wants to merge 5 commits into
KhronosGroup:mainfrom
mklefrancois:khr-materials-retroreflection

Conversation

@mklefrancois

Copy link
Copy Markdown

This sample asset accompanies KhronosGroup/glTF#2610, which proposes the KHR_materials_retroreflection extension.

The scene contains two traffic cones side by side: one with a retroreflective material using both retroreflectionFactor and retroreflectionTexture, and one without the extension for comparison. The retroreflective cone brightens significantly when the light and camera directions are closely aligned, which is the characteristic appearance of real-world retroreflective materials such as high-visibility clothing and road markings.

Traffic cone with and without KHR_materials_retroreflection

Rendered with vk_gltf_renderer.

@mklefrancois
mklefrancois force-pushed the khr-materials-retroreflection branch from 225b3b2 to 271af5e Compare July 8, 2026 15:24
@echadwick-dgg3d

Copy link
Copy Markdown

This is a great example!

I think it needs a few changes, per SubmittingModels:

  • The .glTF JSON file should be named with PascaleCase to match the folder name
  • The glTF asset and its resources should be moved into a \glTF subfolder (Models/TrafficCone/glTF/TrafficCone.gltf).
  • It's missing a README.md with a screenshot folder.
  • It's missing properly formatted license and metadata files.

You can check one of the existing assets to see how things are ideally set up.

@mklefrancois

Copy link
Copy Markdown
Author

Thanks @echadwick-dgg3d, I made many changes and hopefully it meets all requirements.

@mklefrancois
mklefrancois force-pushed the khr-materials-retroreflection branch from e1482b3 to b7b146f Compare August 4, 2026 06:34
@echadwick-dgg3d

Copy link
Copy Markdown

Looking good. One discrepancy, the readme says the screenshot is from the sample viewer, but the image shows evidence of pathtracing (shadows & soft reflections on the ground plane) which the viewer does not support. Which renderer was it created with? I think it's ok if it's not the glTF Sample Viewer, since we do have other assets with pathtraced screenshots.

Bring the KHR_materials_retroreflection test model in line with
SubmittingModels.md:

- Rename to PascalCase and move the asset + resources into glTF/
  (traffic_cone.gltf/.bin and images/*.png -> glTF/TrafficCone.*)
- Replace license.txt with generated LICENSE.md and add metadata.json
- Add README.body.md (Legal section omitted; states it is a test model
  for the extension) and generate README.md via util/model.php
- Add catalog and large screenshots under screenshot/
- Regenerate repo-wide indexes (Models.md, Models-extension.md,
  model-index.json, .reuse/dep5)
@mklefrancois
mklefrancois force-pushed the khr-materials-retroreflection branch from b7b146f to 796da0d Compare August 4, 2026 15:07
@mklefrancois

Copy link
Copy Markdown
Author

Thanks for pointing it out, I took another model as template and forgot to modify this. The renderer is vk_gltf_renderer. Updating the readme.

@echadwick-dgg3d

Copy link
Copy Markdown

A couple more points I noticed:

Is there a reason why the two materials use "metallicFactor": 0.5,? Any metallic values which are not 0 or 1 are non-physical in the metallic-roughness shading model, so this can lead to unpredictable behavior in renderers. The general advice is to only use grays for anti-aliasing in a metallic texture.

Also, the two gray textures ConeBaseMat_metallicRoughness.png and ConeBaseMat_retroreflective.png could ideally be 8bit grayscale format instead of 24bit.

@mklefrancois

Copy link
Copy Markdown
Author

Thanks @echadwick-dgg3d, good catches. Fixed both.

Setting metallic to 0 like you suggested actually made the retroreflection almost disappear. It makes sense once you look at the MRM model (Portsmouth et al.): the retroreflection is basically the specular lobe bounced back toward the light, so its strength comes from the specular reflectance. That metallicFactor: 0.5 was faking that reflectance — exactly the non-physical trick you flagged. On a proper dielectric (F0 ≈ 0.04) there's almost nothing left to bounce back.

So instead of cheating with metallic, I gave the tape a real dielectric specular via KHR_materials_specular (masked to the stripes). The paper actually calls for this — it says F for retroreflectors should be treated as an empirical value rather than a smooth-surface Fresnel, since the real tape scatters through glass beads / corner cubes.

For the textures: both are 8-bit grayscale now (~55% smaller). They were also identical, so I merged them into one image and dropped the duplicate (metallic-roughness reads G/B, retroreflection reads R).

The two materials are now identical; the only difference is the KHR_materials_retroreflection extension on the left one.

@mklefrancois
mklefrancois force-pushed the khr-materials-retroreflection branch 2 times, most recently from 1225c28 to 89ab02d Compare August 6, 2026 16:29
@echadwick-dgg3d

echadwick-dgg3d commented Aug 6, 2026

Copy link
Copy Markdown

Setting metallic to 0 like you suggested actually made the retroreflection almost disappear. It makes sense once you look at the MRM model (Portsmouth et al.): the retroreflection is basically the specular lobe bounced back toward the light, so its strength comes from the specular reflectance. That metallicFactor: 0.5 was faking that reflectance — exactly the non-physical trick you flagged. On a proper dielectric (F0 ≈ 0.04) there's almost nothing left to bounce back.

So instead of cheating with metallic, I gave the tape a real dielectric specular via KHR_materials_specular (masked to the stripes). The paper actually calls for this — it says F for retroreflectors should be treated as an empirical value rather than a smooth-surface Fresnel, since the real tape scatters through glass beads / corner cubes.

Awesome (though I don't think I advised setting it to zero). Could you add your info in the readme, so people can learn why it's needed and how they can reproduce this effect with their own assets?

Does the readme need to be updated to list the specular extension?

Have you run this asset through the glTF Validator? I think there might be an unused texcoord on the floor, but this is a pretty minor issue I think.

It might seem like a lot of work to get something into the repo, but it's worth the effort to have a bunch of well-formed assets. Thanks for all your work on this!

- Set metallicFactor to 0 on both cones; 0.5 was non-physical. The MRM
  retroreflection redirects the specular lobe, so its strength comes from
  specular reflectance -- provide it via KHR_materials_specular on the
  stripes instead of faking it with metalness.
- Re-encode the metallic-roughness / retroreflection textures to 8-bit
  grayscale; the two were byte-identical, so merge into one image and drop
  the duplicate (metallic-roughness reads G/B, retroreflection reads R).
- Both cone materials are now identical except the KHR_materials_retroreflection
  extension on ConeMatRetro.
- Align the directional light with the view so the effect self-demonstrates;
  refresh screenshots.
@mklefrancois
mklefrancois force-pushed the khr-materials-retroreflection branch from 89ab02d to 75801d5 Compare August 7, 2026 14:34
@mklefrancois

Copy link
Copy Markdown
Author

Thanks! I really appreciate the thorough review and attention to details. This will help when we will bring the asset for opacity micromaps!

And you're right — the "set to 0" was my call; you said 0 or 1, and 0 is the physical one for a plastic cone.

Added a Materials section to the README explaining why KHR_materials_specular is needed — retroreflection redirects the specular lobe, so a plain dielectric (F0 ≈ 0.04) makes it barely visible.

The extensions are automatically added by the script. I have regenerated it, and KHR_materials_specular, KHR_lights_punctual now appears to the extensions list.

Good catch on the floor — an unused TEXCOORD_0 (the plane material has no textures), so I removed it and its orphaned accessor/bufferView. Ran it through the glTF Validator: 0 errors, 0 warnings. The only remaining message is an info that the validator doesn't yet know KHR_materials_retroreflection, which is expected.

Thanks again for the review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants