How to fix z fighting of lines

I want to display the coordinate axes and grid as shown in the image. However, the coordinate axes and grid z-fight and look messy.

I wrote the following code to solve this problem using polygon offset, but it does not work. What should I do?

/**
 * 座標軸。
 */
export class Axes extends THREE.LineSegments {
    /**
     *
     * @param size
     */
    constructor(size = 1) {
        const vertices = [0, 0, 0, size, 0, 0, 0, 0, 0, 0, size, 0, 0, 0, 0, 0, 0, size];
        const colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0, 0, 0, 1, 0, 0.6, 1];

        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
        geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

        const material = new THREE.LineBasicMaterial({ vertexColors : true, toneMapped : false });
        material.polygonOffset = true;
        material.depthTest = true;
        material.polygonOffsetFactor = 1;
        material.polygonOffsetUnits = 0.1;

        super(geometry, material);
    }

    dispose() {
        this.geometry.dispose();
        (this.material as THREE.LineBasicMaterial).dispose();
    }
}

Unfortunatelly, I do not get z-fighting between lines on my computer. Maybe it depends on the graphical card? In any case, try the following ideas:

  • polygonOffset has no effect on lines, use if only for polygons
  • turn off depthTest-ing in the material, so that drawing lines ignores depth data
  • set renderOrder of the Axes instance, to insure it is drawn after the grid

Does the following demo work fine on your computer?

https://codepen.io/boytchev/full/xxQLOmy

image

4 Likes

Thank you very much!

Your demo worked correctly. For my use case, this method is sufficient. However, I think setting the depth test to false might be a problem for some use cases.

1 Like

Yes, turning off depth testing has side effects. Sometimes it is possible to replace it with turning off depth writing – it has other side effects. If both are not possible because of their side effects, then the axes could be shifted slightly, so that to avoid z-fighting. As a last option - instead of lines use very thin cylinders, because they are meshes and they can use polygon offset properties.

It could also be a precision error. Try narrowing the camera near and far values and see if that mitigates the problem. There have been several threads in the past couple of months which described inconsistencies between browsers or platforms (Mac most notably) which turned out to be precision errors.

1 Like