Page MenuHome

Undefined behaviour in specular_occlusion is visible on Apple M1
Closed, ResolvedPublic

Description

System Information
Operating system: macOS Big Sur
Graphics card: Apple M1

Blender Version
Broken: (example: 2.93alpha, 8936550269333297f6c083c92c90f11660b22e33, Sun Mar 14 15:10:18 2021 +0100 "EEVEE: Specular Occlusion: Avoid overdarkening on smooth surfaces") until current version
Worked: The versions before

Short description of error
Switching the default defaultcube scene to the matrial view immediately shows the defaultcube in camo pattern of dark shapes.

Exact steps for others to reproduce the error

  1. Use an Apple M1, it is an error that probably doesn't show up on other machines but it is no driver error.
  2. Create new default scene
  3. Switch on material view
  4. Watch camo pattern of dark shapes.
  5. Switch on ambient occlusion
  6. Watch defaultcube in it's usual correct shape.

Long description of error

  1. In the function specular_occlusion (in ambient_occlusion_lib.glsl) visibility_error is defined but not initialized.
  2. occlusion_eval is called and when int(aoSettings) & USE_AO is false (ambient occlusion is off) the function returns leaving visibility_error undefined.
  3. Back in specular_occlusion "visibility *= mix(safe_rcp(visibility_error), 1.0, roughness);" visibility_error contains now a wide range of undefined values.

Proposed fix (which works for me): Set visibility_error to zero in the early exit case of occlusion_eval:

diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
index dc5c048422b..9836aa49cd0 100644
--- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
@@ -200,6 +200,7 @@ void occlusion_eval(OcclusionData data,
 {
   if ((int(aoSettings) & USE_AO) == 0) {
     visibility = data.custom_occlusion;
+    visibility_error = 0.0;
     bent_normal = N;
     return;
   }