# Maintaining same visual angle of stacked layers

**URL:** https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995
**Category:** Coding Questions
**Created:** [February 27, 2024, 3:25am UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995 "2024-02-27T03:25:34Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)
#### Post date: [February 27, 2024, 3:25am UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/1 "2024-02-27T03:25:34Z")

</div>

What I’m trying to achieve is cross-sections of a 3D noise cube. The look I’m going for is like this:

 ![3d_layers_same](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/2/5/25f945973bda08b54b47443713a94c256f31a415.jpeg)

But what I’m getting is more like this given the default perspective of the environment giving the conical perspective:  
 ![3d_layers_perspective](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/8/c/8cabc052b360d8c616c97f3f29acb342dd4cca10.jpeg)

This is the result I’m getting:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/5/b/5b2666be362a3ab13611485dc9073873952c1b81.png)

The first thing I tried was using ortho(), but that doesn’t quite achieve the same look of having some kind of depth of field. Just flattens it like this:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/c/c/cccd55aa539537d735f9948cef28ad8a7fbd3a52.png)

I’ve also tried changing them from layered across the X to the Z axis and rotating them but they then have different sizes because it is making the ones lower on the Z axis smaller.

I’ve also tried to find a hack where I change the rotation for each depending on their screen location, but I can’t get a consistent formula that works to make the layers appear at a consistent angle across all the board.

Would changing the position of the camera to the left side of the screen achieve the effect? I’ve never played with that function. Beyond that, I’m not sure how else to tackle this problem. Would appreciate any suggestions. Bonus points if anyone has a way of making each layer have a higher strokeWeight() border so when the layers overlap, they don’t just blend into each other.

Full code:

```auto
color bg = color(18,18,18);
color clrA = color(57,190,227);
color clrB = color(142,57,227);

ArrayList<Layer> noiseLayers;
int numIters = 6;
float layerDiff = 0.2;
float layerSpace = 80;
int numCols, numRows;
float boxSize = 15;
int marginW = 80;
int marginH = 50;
int canvasW, canvasH;
float halfCanvasW, halfCanvasH;
float seedVal = random(0,1000000);
float yRot = 2.25;

void setup() {
  size(1600, 850, P3D);
  background(bg);
  
  canvasW = width - (marginW*2);
  canvasH = height - (marginH*2);
  halfCanvasW = canvasW / 2;
  halfCanvasH = canvasH / 2;
  numCols = int(canvasW / boxSize);
  numRows = int(canvasH / boxSize);
  numCols = numRows;
  noiseLayers = new ArrayList<Layer>();
  makeLayers();
  
  smooth(8);
  ortho();
}

void draw() {
  background(bg);
  
  for(Layer l : noiseLayers){
    l.render();
  }
}

void makeLayers() {
  for(int i=0; i<numIters; i++){
    float xPos = width/2 + marginW - (floor(numIters/2) * (canvasW / numIters)) + (i * (canvasW / numIters));
    float zOff = i * layerDiff;
    color clr = lerpColor(clrA, clrB, map(i, 0, numIters, 0, 1));
    float terrain[][] = new float[numCols][numRows];
    float yOff = 0.0;
    for (int y=0; y<numRows; y++) {
      float xOff = 0.0;
      for (int x=0; x<numCols; x++) {
        terrain[x][y] = map(noise(xOff, yOff, zOff), 0, 1, -30, 30);
        xOff += 0.3;
      }
      yOff += 0.3;
    }
    noiseLayers.add(new Layer(xPos, zOff, clr, terrain));
  }
}

class Layer {
  float layerPos;
  float zOff;
  color colorSel;
  float[][] terrain;
  
  Layer(float thePos, float theZ, color theColor, float[][]thePlane) {
    layerPos = thePos;
    zOff = theZ;
    colorSel = theColor;
    terrain = thePlane;
  }
  
  void update() {
    //make changes as needed
  }
  
  void render() {
    strokeWeight(1);
    stroke(colorSel);
    fill(bg);
    //noFill();
    pushMatrix();
    translate(layerPos, height/1.35);
    rotateY(-PI/yRot);
    rotateZ(PI/5);
    translate(-(canvasW/2), -(canvasH/2));
    for(int y=0; y<numRows-1; y++){
      beginShape(QUAD_STRIP);
      for(int x=0; x<numCols; x++){
        vertex(x*boxSize, y*boxSize, terrain[x][y]);
        vertex(x*boxSize, (y+1)*boxSize, terrain[x][y+1]);
      }
      endShape();
    }
    popMatrix();
  }
}

```

---

<div class="post-metadata">

### Author: ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)
#### Post date: [February 27, 2024, 3:59am UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/2 "2024-02-27T03:59:57Z")

</div>

I added the following to the draw function:  
`camera(width/14, height/2, (height/2.0) / tan(PI*30.0 / 180.0), width/4, height/2, 0, 0, 1, 0);`

Which gives the result of:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/a/6/a67cddc6f52257936a32a5a417e55cee12143ba1.png)

It’s closer, but the ones to the right still appear “flattter” / less angled (as well as smaller) and don’t convey the definition of the noisy layer like the ones on the left do.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 27, 2024, 8:29am UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/3 "2024-02-27T08:29:01Z")

</div>

One approach might be PGraphics

When you have one PGraphics with same angle for each slide you are good.

There might arise difficulties when you display them, maybe you need some transparency there.

---

<div class="post-metadata">

### Author: ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)
#### Post date: [February 27, 2024, 2:52pm UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/4 "2024-02-27T14:52:17Z")

</div>

In this approach, I would draw each layer at center screen, then save as PGraphics, and draw it elsewhere on the screen in the main loop? That sounds like it could work. I’ll give it a shot a little later.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 27, 2024, 3:10pm UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/5 "2024-02-27T15:10:56Z")

</div>

> [@travis.stdenis](#):
>
> I would draw each layer at center screen, then save as PGraphics

No need to draw to the screen in the first place.

you can draw directly to the PGraphics

you can even have an array of PGraphics

* * *

**Here is an example**

_As you can see the position of the pg doesn’t change the angle of the box in the pg._

```auto
PGraphics pg ;

// -------------------------------------------------------------------------------------------------------------------------

void setup() {
  size(1900, 1000, P3D);
  makePG();
}

void draw() {
  background(10);
  image(pg, mouseX, mouseY);
}

// -----------------------------------------------------------------------------------------------------------------------------------

void makePG() {

  pg = createGraphics(400, 400, P3D);

  pg.beginDraw();
  pg.background(100);

  pg.fill(255, 0, 0);
  pg.stroke(255);

  pg.lights();
  pg.translate(pg.width/2+16, pg.height/2-162, 0);

  pg.box(66, 12, 66);

  pg.endDraw();
}

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 27, 2024, 3:39pm UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/6 "2024-02-27T15:39:48Z")

</div>

new version, showing the same pg 10 times,  
maintaining visual angle

```auto
PGraphics pg;

// -------------------------------------------------------------------------------------------------------------------------

void setup() {
  size(1900, 1000, P3D);
  makePG();
}

void draw() {
  background(10);

  translate(mouseX, mouseY);
  for (int i=0; i<10; i++) {
    image(pg, 0, 12+i*66);
  }
}

// -----------------------------------------------------------------------------------------------------------------------------------

void makePG() {

  pg = createGraphics(400, 99, P3D);

  pg.beginDraw();
  pg.background(10);
  pg.lights();

  pg.fill(255, 0, 0);
  pg.stroke(255);

  pg.pushMatrix();
  pg.translate(pg.width/2+22, 1+33*1, 0);
  pg.box(66, 12, 66);
  pg.popMatrix();

  pg.endDraw();
}
//

```

---

<div class="post-metadata">

### Author: ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)
#### Post date: [February 29, 2024, 1:17am UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/7 "2024-02-29T01:17:34Z")

</div>

Reconfigured the code to put it into a PGraphic and it works for the most part. Here’s a sample without the rotation on the Z axis:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/f/e/fefc4b99b4a4923fb8ac301ef9fced6f9ba6d5a4.jpeg)

However, when I uncomment this line:  
`plane.rotateZ(PI/5);`  
I get some clipping that I can’t figure out how to account for.

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/4/3/4300a3a1db364be6b1b52703281afc1c5105a93f.jpeg)

It looks like it’s lopping off the top part of the rotated planes as if they rotate out of the canvas. But I don’t know how to define the createGraphics() size to accommodate the rotation. Even when I double the width and height, it still lops it off.

The other issue has to do with the fill and graphic transparency. The plane.fill() command to make sure the plane don’t bleed into each other and the plane.clear() command to put transparency of overall PGraphic do not appear to be working. And it isn’t that they cancel each other out as I turn them on and off to the same effect.

Full code:

```auto
import processing.svg.*;
boolean makeSVG = false;
import processing.pdf.*;
boolean makePDF = false;
String docBase = "noise_layers";
String docName = "";

color bg = color(18,18,18);
color clrA = color(57,190,227);
color clrB = color(142,57,227);

ArrayList<Layer> noiseLayers;
int numIters = 9;
float layerDiff = 0.2;
float layerSpace = 80;
int numCols, numRows;
int boxSize = 15;
int xSize, ySize;
int marginW = 80;
int marginH = 50;
int canvasW, canvasH;
float halfCanvasW, halfCanvasH;
float seedVal = random(0,1000000000);
float yRot = 2.25;

void setup() {
  size(1600, 850, P3D);
  background(bg);
  
  canvasW = width - (marginW*2);
  canvasH = height - (marginH*2);
  halfCanvasW = canvasW / 2;
  halfCanvasH = canvasH / 2;
  numCols = int(canvasW / boxSize);
  numRows = int(canvasH / boxSize);
  numCols = numRows;
  xSize = numCols * boxSize;
  ySize = numRows * boxSize;
  noiseLayers = new ArrayList<Layer>();
  makeLayers();
  
  smooth(8);
}

void draw() {
  background(bg);
  
  for(Layer l : noiseLayers){
    l.render();
  }
}

void makeLayers() {
  for(int i=0; i<numIters; i++){
    float xPos = width/2 - ((layerSpace * numIters) / 2) + (layerSpace / 2) + (i * layerSpace);
    float zOff = i * layerDiff;
    float yOff = 0.0;
    color clr = lerpColor(clrA, clrB, map(i, 0, numIters, 0, 1));
    float terrain[][] = new float[numCols][numRows];
    for(int y=0; y<numRows; y++){
      float xOff = 0.0;
      for(int x=0; x<numCols; x++){
        terrain[x][y] = map(noise(xOff, yOff, zOff), 0, 1, -30, 30);
        xOff += 0.3;
      }
      yOff += 0.3;
    }
    
    PGraphics plane = createGraphics(width, height, P3D);
    plane.beginDraw();
    plane.strokeWeight(1);
    plane.stroke(clr);
    plane.fill(bg);
    plane.clear();
    plane.pushMatrix();
    plane.translate(width/2, height/2);
    plane.rotateY(-PI/yRot);
    plane.rotateZ(PI/5);
    plane.translate(-(canvasW/2), -(canvasH/2));
    for(int y=0; y<numRows-1; y++){
      plane.beginShape(QUAD_STRIP);
      //plane.strokeWeight(1);
      //plane.stroke(clr);
      //plane.fill(bg);
      for(int x=0; x<numCols; x++){
        plane.vertex(x*boxSize, y*boxSize, terrain[x][y]);
        plane.vertex(x*boxSize, (y+1)*boxSize, terrain[x][y+1]);
      }
      plane.endShape();
    }
    plane.popMatrix();
    plane.endDraw();
    
    noiseLayers.add(new Layer(xPos, zOff, clr, terrain, plane));
  }
}

class Layer {
  float layerPos;
  float zOff;
  color colorSel;
  float[][] terrain;
  PGraphics plane;
  
  Layer(float thePos, float theZ, color theColor, float[][] theLayer, PGraphics thePlane) {
    layerPos = thePos;
    zOff = theZ;
    colorSel = theColor;
    terrain = theLayer;
    plane = thePlane;
  }
  
  void update() {
    //make changes as needed
  }
  
  void render() {
    pushMatrix();
    translate (layerPos, 0, -200);
    image(plane, -width/2, 0);
    popMatrix();
  }
}

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 29, 2024, 5:35am UTC](https://discourse.processing.org/t/maintaining-same-visual-angle-of-stacked-layers/43995/8 "2024-02-29T05:35:20Z")

</div>

Wild guess

But can you implement this in the pg

```auto
// Tools 

void avoidClipping() {
  // avoid clipping (at camera): 
  // https : // 
  // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
  perspective(PI/3.0, (float) width/height, 1, 1000000);
}//func

```
