diff --git a/CHANGELOG.md b/CHANGELOG.md
index d1a7d2302271eddd3fca0d1dcf3dc2df5a981e6e..cb1eed9a966244f29a82dfad47394cb9160e5b27 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ Note that since we don't clearly distinguish between a public and private interf
     - [Breaking] Rename `DnatcoConfalPyramids` to `DnatcoNtCs`
 - Improve boundary calculation performance
 - Add option to create & include images in state snapshots
+- Fix SSAO artefacts with high bias values
 
 ## [v3.29.0] - 2023-01-15
 
diff --git a/src/mol-gl/shader/ssao.frag.ts b/src/mol-gl/shader/ssao.frag.ts
index 41850c5ea31f200af46d545731869152bb43baa0..b4d61f5dbd1614f36f6d00207da855e1bcf25e83 100644
--- a/src/mol-gl/shader/ssao.frag.ts
+++ b/src/mol-gl/shader/ssao.frag.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz>
@@ -115,7 +115,7 @@ void main(void) {
     }
     occlusion = 1.0 - (uBias * occlusion / float(dNSamples));
 
-    vec2 packedOcclusion = packUnitIntervalToRG(occlusion);
+    vec2 packedOcclusion = packUnitIntervalToRG(clamp(occlusion, 0.01, 1.0));
 
     gl_FragColor = vec4(packedOcclusion, selfPackedDepth);
 }