Search code examples
graphicsprocessing

Processing: how to make box() appear solid (non-transparent) in 3d mode


I'm trying to create layers of 3d boxes in Processing. I want them to appear solid, so that you can't see the boxes "behind" other boxes, but the way they're displaying makes them seem transparent; you can see the stroke of boxes behind other boxes. How do I make them appear solid?

// number of boxes
int numBox = 300;

// width of each box
int boxWidth = 30;

// number of boxes per row
float numPerRow;

void setup() {
  size(800, 800, P3D);
  pixelDensity(1);
  colorMode(HSB, 360, 100, 100, 100);
  background(40, 6, 85);
  stroke(216, 0, 55);
  smooth(4);
  fill(0, 0, 90, 100);
  
  numPerRow = width / boxWidth;
  
}

void draw() {
  background(40, 6, 85);
  
  translate((boxWidth / 2), 100);
  rotateX(-PI/6);
  rotateY(PI/8);
  
  for (int i = 0; i < numBox; i++) {
    drawBox(i);
    
    if (i == numBox - 1) {
      noLoop();
    }
  }
}

void drawBox(int i) {
  if ((i % 2) == 0) {
    pushMatrix();
    translate(((boxWidth / 2) * i) % width, 20 * floor(i / (2 * numPerRow)));
    translate(0, -((i % 30) / 2));
    box(boxWidth, i % 30, boxWidth);
    popMatrix();
  };
}

Close-up of how the boxes are being displayed:

intersecting rows of cubes that appear as layers of steps


Solution

  • The issue is that the boxes are intersecting and the strokes of these intersecting boxes are what give the appearance of "see through".

    I'm noticing you are using x and y translation, but not z. If you don't plan to increase x, y spacing to avoid intersections, you can easily offset rows on the z axis so rows of boxes appear in front of each other.

    Here's a slightly modified version of your code illustrating this idea:

    // number of boxes
    int numBox = 300;
    
    // width of each box
    int boxWidth = 30;
    
    // number of boxes per row
    float numPerRow;
    
    void setup() {
      size(800, 800, P3D);
      pixelDensity(1);
      colorMode(HSB, 360, 100, 100, 100);
      background(40, 6, 85);
      stroke(216, 0, 55);
      smooth(4);
      fill(0, 0, 90, 100);
    
      numPerRow = width / boxWidth;
    }
    
    void draw() {
      background(40, 6, 85);
    
      translate((boxWidth / 2), 100);
      if(mousePressed){
        rotateX(map(mouseY, 0, height, -PI, PI));
        rotateY(map(mouseX, 0, width, PI, -PI));
      }else{
        rotateX(-PI/6);
        rotateY(PI/8);
      }
    
      for (int i = 0; i < numBox; i++) {
        drawBox(i);
    
        //if (i == numBox - 1) {
        //  noLoop();
        //}
      }
    }
    
    void drawBox(int i) {
      if ((i % 2) == 0) {
        pushMatrix();
        float x = ((boxWidth / 2) * i) % width;
        float y = 20 * floor(i / (2 * numPerRow));
        float z = y * 1.5;
        translate(x, y, z);
        translate(0, -((i % 30) / 2));
        box(boxWidth, i % 30, boxWidth);
        popMatrix();
      };
    }
    

    (Click and drag to rotate and observe the z offset.

    Feel free to make z as interestersting as you need it it.

    Nice composition and colours! (framing (window size) could use some iteration/tweaking, but I'm guessing this is WIP))

    rows of stepped cubes offset in depth to avoid intersections