CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.8k stars 3.46k forks source link

Verify BRDF for image-based lighting #12028

Closed jjhembd closed 1 month ago

jjhembd commented 4 months ago

Cesium uses the squared roughness to select the LOD of the specular environment map, which appears to be incorrect. The glTF reference implementation uses "perceptual roughness" for environment map LOD selection.

Here are some rough comparisons in Cesium, compared to the reference implementation. Note: for these comparisons, all are using the "Helipad Golden Hour" environment map for the specular component. But Cesium is not using the corresponding coefficients for the diffuse component.

Clearcoat Car Paint model, using squared roughness (current behavior): image

Clearcoat Car Paint model, using perceptual roughness (test): image

Clearcoat Car Paint model, reference implementation: image

At first glance, the squared roughness result in Cesium appears to be noisier. Also the environment map appears to be mirror-flipped relative to the reference?

Barn Lamp model, using squared roughness (this affects both LOD selection and anisotropy calculations): image

Barn Lamp model, using perceptual roughness: image

Barn Lamp model, reference implementation: image

The squared roughness result does not show as much smearing along the brush strokes in the metal, indicating that perceptual roughness should be used for the anisotropy calculations.

We will need to verify the correctness before switching. Cesium's approach has some fundamental differences with the glTF reference implementation which can make comparisons challenging:

jjhembd commented 3 months ago

Material roughness is used in three places for IBL:

  1. Generating the bent normal for anisotropic materials, to point to the appropriate location in the environment map.
  2. Reading the BRDF from a look-up texture.
  3. Selecting the appropriate LOD from the environment map.

We will need to verify which roughness to use in each place. See BrdfLutGeneratorFS.glslto for the generation of our BRDF look-up.

Assuming we store both perceptual roughness and squared ("alpha") roughness on the czm_modelMaterial struct, there are 2 things to keep in mind:

jjhembd commented 3 months ago

A bigger issue for our IBL is the way we handle the diffuse component. We currently expect the user to compute the spherical harmonic from the environment map and set the coefficients manually. Then we sample it and add it directly to the specular component, without any BRDF or Fresnel terms.

jjhembd commented 3 months ago

A bigger issue for our IBL is the way we handle the diffuse component.

The BRDF and Fresnel terms for the diffuse component in the glTF Sample Viewer are actually part of a multi-scattering approximation. The terms are explained toward the end of this very helpful article.

These multi-scattering terms fix energy conservation problems in two main areas:

  1. Brighten the appearance of rough metals. Without the terms, rough metals absorb energy.
  2. Reduce the excessive Fresnel reflection at glancing incidence on dielectrics.

Despite the name, the approximate "multi-scattering" terms are actually cheap to compute, so we should incorporate them into our code in ImageBasedLightingStageFS.glsl.

ggetz commented 2 months ago

As noted in https://github.com/CesiumGS/cesium/pull/12082, once this is complete, some Sandcastles may need updating to ensure the brighter side is facing the camera on initial load.