multiple CSG subtract operations very slow

I’m using Three.js to display a sheet with Hexagone-like holes in 3D:
enter image description here
The raw sheet-data is in SVG Format, where each hexagone is a Polyline.

As you see in the preview picture, the SVG contains alot of hexagones (30.000+ in some cases) which ALL need to be subtracted from the sheet.

For this I’m using the CSG-library for Three.js (Constructive Solid Geometry).

This one: GitHub - Jiro-Digital/three-csg-ts: CSG library for use with THREE.js

It turns out the subtract Method is really slow when a really large array is passed.

This is my source code, notice that I collect every hexagone in an array so that I have to call the subtract() method only once. This already makes it alot faster, but it’s still not fast enough. For 20.000+ hexagones it will take multiple minutes.

loader.load(images.demo, function ( data ) {
  const paths = data.paths;

  const material = new MeshPhongMaterial( {
    color: "silver",
    side: DoubleSide,
    depthWrite: true
  });

  const shapeSheet = SVGLoader.createShapes(paths[0]);
  const geometrySheet =  new ExtrudeGeometry(shapeSheet, {depth: 1, bevelEnabled: false } );
  const meshSheet = new Mesh(geometrySheet);

  let sheetCSG = CSG.fromMesh(meshSheet)
  let hexagoneCSGArray = null;

  for ( let i = 2; i < paths.length; i ++ ) {
    const pathHexagone = paths[i];
    const shapeHexagone = SVGLoader.createShapes(pathHexagone);
    const geometryHexagone = new ExtrudeGeometry( shapeHexagone, { bevelEnabled: false } );
    const meshHexagone = new Mesh(geometryHexagone);
    const hexagoneCSG = CSG.fromMesh(meshHexagone);
    if(hexagoneCSGArray === null) hexagoneCSGArray = hexagoneCSG;
    else hexagoneCSGArray.polygons.push(...hexagoneCSG.polygons);
  }
  let t0 = performance.now()
  sheetCSG = sheetCSG.subtract(hexagoneCSGArray); // this operation takes too long
  let t1 = performance.now()
  console.log((Math.round(((t1 - t0)  / 1000) * 100) / 100) + " Sec")
  const finalMesh = CSG.toMesh(sheetCSG, new Matrix4());
  finalMesh.material = new MeshPhongMaterial(material);
  scene.add( finalMesh );
  renderer.render( scene, camera );
},

Is there a alternative way (faster way) to subtract each hexagone?

If you wanna try it yourself, heres the SVG data: SVG

Maybe need ony one hexagone geometry and useinstancedMeshGeometry or instancedBufferGeometry
and change fragmentShader for uv offsets

2 Likes

Another option is to have a plane with the hexagonal pattern for discard in fragment shader.

2 Likes

Hexagone image with SDF and maybe alphaToCoverage enabled into material if default msaa antialising.

1 Like

@Chaser_Code
@prisoner849

Could anyone of you provide a small code example on what you mean?
I am very, very new to Three.js and I have little to no understanding on what you are talking about.
I tried using InstanceMeshGeometry but the subtract Method doesn’t seem to work with Instanced Meshes.

Quick and rough: Edit fiddle - JSFiddle - Code Playground

Based on shaders from this demo: Robeast (selective bloom)
Reference: Hexagonal Tiling Explained! - YouTube

1 Like

Very simple example:

Pattern here:
dfg2

1 Like