Three.js depth conflict (model flickering) and solution

Mesh surface coincidence rendering test 

The following code creates two coincident rectangular plane Mesh, previewed through the browser, when you rotate the 3D scene, you will find flickering when the model is rendered.

This phenomenon is mainly due to the overlapping of two Mesh, and the computer GPU cannot tell who is in front and who is behind. This phenomenon can be called a deep conflict Z-fighting.

// 两个矩形平面Mesh重合,产生闪烁
// 闪烁原因:两个矩形面位置重合,GPU无法分清谁在前谁在后
const geometry = new THREE.PlaneGeometry(250, 250);
const material = new THREE.MeshLambertMaterial({
    color: 0x00ffff,
    side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geometry, material);


const geometry2 = new THREE.PlaneGeometry(300, 300); 
const material2 = new THREE.MeshLambertMaterial({
    color: 0xff6666,
    side: THREE.DoubleSide,
});
const mesh2 = new THREE.Mesh(geometry2, material2);

look

The distance between two rectangular Mesh

Appropriate offset to solve the depth conflict, the offset size is relatively small compared to the model size, and the visual approximation of the two planes still coincides.

mesh2.position.z = 1;

 

Small gaps, deep conflicts

Depth conflicts can also occur when the gap between two faces is small. From a purely theoretical point of view, you can distinguish between 0 and 0.0000...0000001, but in reality, the precision of the computer GPU is limited

// 当两个面间隙很小,也可能出现深度冲突。
mesh2.position.z = 0.0000000000000000000001;

 also have problems 

 

Effect of perspective projection camera on distance (depth conflict)

  • Step 1: Set the distance difference between the two Mesh planes to 0.1, and there is no model flickering problem caused by depth conflicts
mesh2.position.z = 0;
mesh2.position.z = 0.1;
camera.position.set(292, 223, 185);
  • Step 2: Change the camera .positionproperties. You will find that when the camera is far away from the 3D model, depth conflicts may also occur between the two surfaces. Of course, you can also use the zoom function of the camera control to OrbitControlschange the distance between the camera and the model for observation.
camera.position.set(292*5, 223*5, 185*5)

look at the effect

The projection law of the perspective projection camera is that the distance is small and the near is large. Just like the human eye observes the world, the farther the model is from the camera, the smaller the model rendering effect is, and the distance between the two meshes will also be smaller. When the distance between the two Mesh and the camera is to a certain extent, the distance between the two models will be infinitely close to 0.

webgl renderer set logarithmic depth buffer

The distance between the two rectangular planes is relatively close, with a difference of 0.1

mesh2.position.z = 0;
mesh2.position.z = 0.1;
camera.position.set(292*5, 223*5, 185*5);

When some faces in a 3D scene are relatively close and there is a depth conflict, you can try to set the webgl renderer to set the logarithmic depth buffer logarithmicDepthBuffer: trueto optimize or solve it. logarithmicDepthBuffer: trueIn simple terms, when the distance between the two surfaces is relatively small, it makes it easier for threejs to distinguish between the two surfaces, who is in front and who is behind.

// WebGL渲染器设置
const renderer = new THREE.WebGLRenderer({
    // 设置对数深度缓冲区,优化深度冲突问题
    logarithmicDepthBuffer: true
});

 One thing to note is that when the gap between the two faces is too small or coincident, the logarithmic depth buffer you set for the webgl renderer is also invalid.

mesh2.position.z = 0;
//当两个面重合,logarithmicDepthBuffer: true无效
mesh2.position.z = 0;
//当两个面间隙过小,logarithmicDepthBuffer: true无效
mesh2.position.z = 0.00001;
camera.position.set(292*5, 223*5, 185*5);

 

Guess you like

Origin blog.csdn.net/dabaooooq/article/details/130818082