HidingEdgesBox (LineSegments + modified LineDashedMaterial)

Hi community!
Here is an option of how to build a box of lines, when you see the lines of box sides, that you see only from their back.

Example: https://codepen.io/prisoner849/pen/XWRZqXa?editors=0010
Picture:


Code:

function HidingEdgesBox(w, h, d, color) {
  //box base points
  let basePts = [
    [0, 0, 0],[1, 0, 0],[1, 0, 1],[0, 0, 1],
    [0, 1, 0],[1, 1, 0],[1, 1, 1],[0, 1, 1]
  ].map(p => {return new THREE.Vector3(p[0], p[1], p[2])});
  // box sides normals
  let baseNor = [
    [0, 0, -1], [1, 0, 0], [0, 0, 1], [-1, 0, 0], [0, 1, 0], [0, -1, 0] 
  ].map(n => {return new THREE.Vector3(n[0], n[1], n[2])});
  
  let pts = [];
  let n1 = [];
  let n2 = [];
  
  //bottom
  for(let i = 0; i < 4; i++){
    // bottom
    pts.push(basePts[i].clone());
    pts.push(basePts[(i + 1) > 3 ? 0 : (i + 1)].clone());
    n1.push(baseNor[i].x, baseNor[i].y, baseNor[i].z,baseNor[i].x, baseNor[i].y, baseNor[i].z);
    n2.push(baseNor[5].x, baseNor[5].y, baseNor[5].z,baseNor[5].x, baseNor[5].y, baseNor[5].z);
    // top
    pts.push(basePts[4 + i].clone());
    pts.push(basePts[(4 + i + 1) > 7 ? 4 : (4 + i + 1)].clone());
    n1.push(baseNor[i].x, baseNor[i].y, baseNor[i].z,baseNor[i].x, baseNor[i].y, baseNor[i].z);
    n2.push(baseNor[4].x, baseNor[4].y, baseNor[4].z,baseNor[4].x, baseNor[4].y, baseNor[4].z);
    // middle
    pts.push(basePts[i].clone());
    pts.push(basePts[i + 4].clone());
    n1.push(baseNor[i].x, baseNor[i].y, baseNor[i].z,baseNor[i].x, baseNor[i].y, baseNor[i].z);
    let prev = (i - 1) < 0 ? 3 : (i - 1);
    n2.push(baseNor[prev].x, baseNor[prev].y, baseNor[prev].z,baseNor[prev].x, baseNor[prev].y, baseNor[prev].z);
  }
  
  let g = new THREE.BufferGeometry().setFromPoints(pts);
  g.setAttribute("n1", new THREE.Float32BufferAttribute(n1, 3));
  g.setAttribute("n2", new THREE.Float32BufferAttribute(n2, 3));
  g.translate(-0.5, -0.5, -0.5);
  g.scale(w, h, d);

  let m = new THREE.LineDashedMaterial({
    color: color, 
    dashSize: 0.15, 
    gapSize: 0.07,
    onBeforeCompile: shader => {
      shader.vertexShader = `
        attribute vec3 n1;
        attribute vec3 n2;
        varying float isDiscarded;
        ${shader.vertexShader}
      `.replace(
        `#include <fog_vertex>`,
        `#include <fog_vertex>
        
          vec3 nor1 = normalize(normalMatrix * n1);
          vec3 nor2 = normalize(normalMatrix * n2);
          vec3 vDir = normalize(mvPosition.xyz);
          //vDir = vec3(0, 0, -1);
          float v1 = step( 0., dot( vDir, nor1 ) );
          float v2 = step( 0., dot( vDir, nor2 ) );
          isDiscarded = max(v1, v2);
        `
      );
      console.log(shader.vertexShader);
      shader.fragmentShader = `
        varying float isDiscarded;
        ${shader.fragmentShader}
      `.replace(
        `#include <clipping_planes_fragment>`,
        `
          if ( floor(isDiscarded + 0.1) == 0.0 ) discard;
        #include <clipping_planes_fragment>`
      );
      console.log(shader.fragmentShader)
    }
  });
  let l = new THREE.LineSegments(g, m);
  l.computeLineDistances();
  return l;
}
10 Likes

Is there an arbitrary model applicable method