Atlaslog
Atlaslog / Field Notes / three.js rendering
Field note · three.js rendering

Two coplanar surfaces flicker and get worse with distance

Quick answer

A road surface laid on the ground mesh shimmers in stripes and speckles because both meshes occupy nearly the same plane and the depth buffer cannot rank them. Stripe width grows with camera distance and with an oversized near/far range.

Last verified 2026-11-03 · Multiple versions · Cite this page
Applies to: three.js
Symptom
Checklist
  1. Hide the upper mesh to confirm coplanarity rather than normals or lighting.
  2. Print both meshes' world bounding boxes and compute the minimum separation.
  3. Check the camera near/far ratio; anything beyond 1:100000 is visibly unstable.
  4. Pull the camera from 5 m to 5 km to confirm stripe width tracks distance.
Fix

Add polygonOffset: true with polygonOffsetFactor -1 and polygonOffsetUnits -1 to the upper MeshStandardMaterial, or lift it 1-2 cm (road.position.y = ground.position.y + 0.02); for very deep scenes enable logarithmicDepthBuffer with near 0.1 and far 20000.

Code
var b1 = new THREE.Box3().setFromObject(ground);
var b2 = new THREE.Box3().setFromObject(road);
console.log('上层最小 y', b2.min.y, '下层最大 y', b1.max.y);
// 上层最小 y 0.0004  下层最大 y 0.0000  间距 0.4 毫米
var roadMat = new THREE.MeshStandardMaterial({
  map: roadTexture,
  polygonOffset: true,
  polygonOffsetFactor: -1,
  polygonOffsetUnits: -1
});
Watch out
All 120 field notesChinese originalRunnable examples
English edition written for Atlaslog from the original Chinese field note. Code is unchanged and runs as-is.
Cite this page

Atlaslog (2026). Two coplanar surfaces flicker and get worse with distance. https://www.jingweizhi.com/en/cookbook/three-z-fighting.html (accessed 2026-11-03).