Skip to content

3.1.1: metals under flat ambient, visionOS PBR maps, occlusion UV set, mirrored nodes - #449

Merged
doranteseduardo merged 5 commits into
developfrom
feat/311-gltf-pbr
Nov 9, 2026
Merged

doranteseduardo merged 5 commits into
developfrom
feat/311-gltf-pbr

Conversation

@doranteseduardo

Copy link
Copy Markdown
Member

Summary

The rendering gaps left after 3.1.0's glTF work, found by checking DamagedHelmet texture by texture against three.js and a 8,464-model corpus against the spec.

Shaders

  • Ambient by metalness (GL pbr_const_amb, Metal vro_pbr_shade): without an environment map the flat ambient term ignored metalness, so metals lit like matte paint. It is now scaled by 1 - metalness, as three.js and Filament do. With it, DamagedHelmet's metallic-roughness map changes 27% of its pixels in three.js and now visibly in Viro too (it was 7%).
  • normalTexture.scale and occlusionTexture.strength reach the shaders (material_normal_scale, material_ao_strength); both default to 1, so nothing changes for materials that do not set them.
  • Occlusion on a second UV set: VROGeometrySourceSemantic::Texcoord1, a geometry modifier that passes it to the fragment stage, and an AO modifier that samples it. All 16 guaranteed GL attribute slots were taken; it binds at 6, the EdgeCrease slot no shader reads (VRX subdivision data only).

visionOS (Metal)

  • pbr_lighting_fragment_maps: base color, normal, metallic-roughness, occlusion and emissive maps, with the glTF factors and the emissive map's own transform. The Metal PBR path read the base color only, so DamagedHelmet drew as a white silhouette.
  • The normal map's tangent frame comes from screen-space derivatives: no tangent attribute, no change to the vertex descriptor.
  • Maps bind at fragment texture 8-11 through VROMaterialSubstrateMetal::getIndexedTextures, past the shadow and IBL textures at 4-7; absent maps get the blank texture and are skipped by pbr_maps bits. Occlusion on a second UV set is left out here.

Loader

  • Occlusion on its own TEXCOORD_n loads that set as Texcoord1 (VROMaterialVisual::setTexcoordSet).
  • Mirrored nodes (negative world determinant, unskinned) get their triangle indices reversed, so back-face culling keeps the right faces.

visionOS test app

ios/ViroKitVisionOSTest builds again: the generator compiles viro's shared-space sources, a stub ViroReact module map stands in for the pod's module, MetalKit and Accelerate are linked, and the GLBs are bundled. The window is smaller so it does not hide the scene. Pairs with a viro change that adds DamagedHelmet to the bridge's test scene.

Notes

  • Check when upgrading: a metallic model without a lightingEnvironment looks darker than in 3.1.0; that is glTF's and three.js's result. In the release notes.
  • CHANGELOG.md gains v3.1.1 (undated until release); RELEASE_NOTES.md is now 3.1.1's.

Testing

  • Web build against three.js 0.170: DamagedHelmet texture ablation (normal, occlusion, metallic-roughness, emissive), synthetic GLBs for occlusion on TEXCOORD_1 and for a mirrored node (both now match the reference), and 13 showcase/Khronos models 3.1.0 vs 3.1.1: 10 identical, the 3 with metal parts darker as intended.
  • visionOS: the test app in the Vision Pro simulator renders DamagedHelmet with all its maps; on 3.1.0 it is a white silhouette.
  • Metal shaders compile for xros; the visionOS xcframework builds; iOS and Android build in progress.

@doranteseduardo
doranteseduardo merged commit 4543b6c into develop Nov 9, 2026
4 checks passed
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.

3 participants