Skip to content

Conversation

mrdoob
Copy link
Owner

@mrdoob mrdoob commented Oct 17, 2025

Description

This PR improves the physical accuracy of the PBR implementation with better energy conservation and ambient occlusion handling.

Changes

1. Multi-bounce ambient occlusion

  • Added gtaoMultiBounce() function to account for inter-reflections based on surface albedo
  • Prevents over-darkening of bright materials in occluded areas
  • Each light bounce contributes based on material color (bright surfaces bounce more light)

2. Improved specular occlusion for IBL

  • Enhanced computeSpecularOcclusion() with better roughness falloff
  • Uses perceptually linear mapping (roughness²) for more accurate behavior
  • Rough surfaces now correctly show less occlusion influence (they integrate light from wider cone)

Benefits

  • Natural ambient occlusion: Bright surfaces stay bright, dark surfaces stay dark
  • Physically accurate: Light bounces based on albedo rather than assuming black occlusion
  • Better IBL reflections: Specular occlusion now correctly varies with roughness
  • Visual quality: Materials with AO maps look significantly more realistic

Performance

Minimal impact - multi-bounce AO adds ~3 multiply-adds per pixel. No additional texture lookups.

Compatibility

All changes are backwards compatible and always enabled. Works with existing AO maps, no API changes required.

Technical Details

Based on research by Jorge Jimenez (GTAO) and Sébastien Lagarde (Frostbite). Uses polynomial approximation to accumulate infinite light bounces efficiently.

Comparisons

https://raw.githack.com/mrdoob/three.js/dev/examples/index.html#webgl_animation_keyframes
https://raw.githack.com/mrdoob/three.js/multibounce-ao-specular/examples/index.html#webgl_animation_keyframes

Before After Diff
image image image

https://raw.githack.com/mrdoob/three.js/dev/examples/index.html?q=gltf#webgl_loader_gltf_compressed
https://raw.githack.com/mrdoob/three.js/multibounce-ao-specular/examples/index.html?q=gltf#webgl_loader_gltf_compressed

Before After Diff
image image image

https://raw.githack.com/mrdoob/three.js/dev/examples/index.html#webgl_random_uv
https://raw.githack.com/mrdoob/three.js/multibounce-ao-specular/examples/index.html#webgl_random_uv

Before After Diff
image image image

Copy link

github-actions bot commented Oct 17, 2025

📦 Bundle size

Full ESM build, minified and gzipped.

Before After Diff
WebGL 349.17
84.67
349.66
84.83
+482 B
+156 B
WebGPU 603.02
169.12
603.02
169.12
+0 B
+0 B
WebGPU Nodes 601.63
168.88
601.63
168.88
+0 B
+0 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Before After Diff
WebGL 480.83
119.42
481.31
119.58
+482 B
+156 B
WebGPU 672.44
184.55
672.44
184.55
+0 B
+0 B
WebGPU Nodes 614.95
167.9
614.95
167.9
+0 B
+0 B

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.

1 participant