# Draw order in 3D

**URL:** <https://discourse.processing.org/t/draw-order-in-3d/4789>\
**Category:** Coding Questions\
**Created:** [October 24, 2018, 1:00am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789 "2018-10-24T01:00:28Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![garroad\_ran](https://avatars.discourse-cdn.com/v4/letter/g/f08c70/32.png) [@garroad\_ran](https://discourse.processing.org/u/garroad_ran)\
**Post date:** [October 24, 2018, 1:00am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/1 "2018-10-24T01:00:28Z")

</div>

I’m getting into 3d for the first time and I’m not quite sure how I’m supposed to handle draw order.

The easiest way to explain my question is probably with an image and code.  
 ![Screenshot%20from%202018-10-24%2009-58-23](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/36a7b7e0e98b9122e182649e853c283a6f2e8dca.png)

```auto
void setup() {
  size(1280, 720, P3D);
  camera = new PeasyCam(this, 500);
}

void draw() {
  background(0);

  // grey sphere
  stroke(150);
  fill(255);
  sphere(50);
  
  // blue sphere
  translate(150, 150, 150);
  stroke(0, 0, 255);
  sphere(50);
}

```

In this image, the camera is positioned on the side of the grey sphere, with the blue sphere in the back (that’s why it appears smaller, even though both spheres have a radius of 50). Despite that, the blue sphere is rendered overtop of the grey one.

Intuitively, I would expect that, given this camera angle, the grey sphere should block the view of the blue one, even though the blue one was rendered last. What am I missing here?

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [October 24, 2018, 4:37am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/2 "2018-10-24T04:37:25Z")

</div>

Try this. Blue sphere behind grey sphere. Works fine.

```auto
void setup() {
  size(1280, 720, P3D);
 // camera = new PeasyCam(this, 500);
}

void draw() {
  background(0);
  translate(width/2,height/2);

  // grey sphere
  stroke(150);
  fill(255);
  sphere(50);
  
  // blue sphere
  translate(50,50,-50);
  stroke(0, 0, 255);
  sphere(50);
}

```

---

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [October 24, 2018, 5:31am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/3 "2018-10-24T05:31:51Z")

</div>

The Processing compiler renders the shapes in the order you write it in. Since the gray sphere is after the blue sphere, the blue sphere would be first.

If it was the opposite, that means everything would be covered by the background! 🙂

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [October 24, 2018, 6:52am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/4 "2018-10-24T06:52:03Z")

</div>

> [@Sarah](#):
>
> The Processing compiler renders the shapes in the order you write it in. Since the gray sphere is after the blue sphere, the blue sphere would be first.

This might be true in 2D mode. It is not true in 3D mode! Consider the code in my post, above. The blue sphere is drawn in draw() after the grey one, yet it appears behind it!

---

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [October 24, 2018, 7:06am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/5 "2018-10-24T07:06:44Z")

</div>

I never knew! You can ignore my post then 🙂

---

<div class="post-metadata">

**Author:** ![Lexyth](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lexyth/32/7403_2.png) [@Lexyth](https://discourse.processing.org/u/Lexyth)\
**Post date:** [October 24, 2018, 9:54am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/6 "2018-10-24T09:54:36Z")

</div>

Or if you think about it like Reality, if you draw a picture you can Cover up other colors by Drawing after the first, But if you take 3D it’s like placing Blocks. You can place things behind another Block that is already there, then it still wouldn‘t Show, since the 1st one Blocks the view. You can also use this method to draw a 2D picture with 3D Planes/points and modify it, just by changing the z Position of the planes/points, no matter in what Order you draw them.

---

<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:** [October 24, 2018, 1:02pm UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/7 "2018-10-24T13:02:37Z")

</div>

As it has been said:

- In 2D the draw order determines which shape is before another (and covers it). Like on a canvas, the shape which gets drawn first is painted over by shapes that are drawn later.

- In 3D the draw order does not matter. Instead, processing calculates which shape is in front and which shape in the back. This determines what shape is before another shape (and covers it). This is determined by the Z-Position of a shape.

You are not drawing on a canvas but placing shapes in a 3D **room**. Think of the surface of a table, with `translate()`, the x parameter places left/right, the y parameter places above the table (up/down), and the last Parameter, the z parameter moves the shape towards you or away from you parallel to the table surface (back / forth).  
If you rotate the entire scene, you can see the placement of the shapes.

This sketch shows a better handling of the spheres in a function `sphereAt`.

Chrisir

```auto

final color RED = color(255, 0, 0);
final color GREEN = color(0, 255, 0);
final color BLUE = color(0, 0, 255);
final color GRAY = color(150);

void setup() {
  size(1280, 720, P3D);
  // camera = new PeasyCam(this, 500);
}//setup

void draw() {
  background(0);
  lights(); // everything looks better with lights()
  sphereAt (width/2, height/2, 0, GRAY);
  sphereAt (width/2+50, height/2+50, -50, BLUE);
} // draw 

void sphereAt ( float x, float y, float z, 
  color colorSphere) {

  pushMatrix(); // store Matrix 
  translate(x, y, z); // position
  noStroke(); // no lines on the sphere  
  fill(colorSphere); // fill color of the sphere 
  sphere(50); // size of the sphere = 50 
  popMatrix(); // restore Matrix 
  //
}//sphereAt
//

```

---

<div class="post-metadata">

**Author:** ![garroad\_ran](https://avatars.discourse-cdn.com/v4/letter/g/f08c70/32.png) [@garroad\_ran](https://discourse.processing.org/u/garroad_ran)\
**Post date:** [October 24, 2018, 5:37pm UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/8 "2018-10-24T17:37:07Z")

</div>

Hey all, thanks for the responses! I haven’t had a chance to go through and try them yet, but I’m still working on this and will let you know if the problem was solved soon.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [October 24, 2018, 8:45pm UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/9 "2018-10-24T20:45:50Z")

</div>

The issue above was with translateZ(-150) vs translateZ(150). So a question of which direction is forward / back.

Also notice that coordinates when using PeasyCam work differently than the default 3D cam.

Even once this is worked out:

Note however, with transparent object 3D CAN still sometimes have problems with drawing behind-things in front of in-front things. For fixing that, use `hint()`.

> [@Program to test hint() with transparency](https://discourse.processing.org/t/program-to-test-hint-with-transparency/4361):
>
> A small Processing program to test the effect on transparency of enabling and disabling these settings: hint(DISABLE\_DEPTH\_TEST); // or ENABLE\_ hint(DISABLE\_DEPTH\_SORT); // or ENABLE\_ hint(DISABLE\_DEPTH\_MASK); // or ENABLE\_ boolean b[] = new boolean[3]; void setup() { size(800, 600, P3D); hint(DISABLE\_DEPTH\_TEST); hint(DISABLE\_DEPTH\_SORT); hint(DISABLE\_DEPTH\_MASK); } void draw() { background(255); fill(0); text("DEPTH\_TEST " + b[0]…

This can also apply to strokes – so if you are rendering a sphere with strokes, that can be the issue. See hamoids demo sketch and try clicking settings on and off to get a sense of how strokes can pop-through in surprising ways.

---

<div class="post-metadata">

**Author:** ![garroad\_ran](https://avatars.discourse-cdn.com/v4/letter/g/f08c70/32.png) [@garroad\_ran](https://discourse.processing.org/u/garroad_ran)\
**Post date:** [October 25, 2018, 2:49am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/10 "2018-10-25T02:49:45Z")

</div>

Hmm, is there a specific way to make objects be non-transparent? I’ve played around with the `hint()` settings, but they don’t seem to be affecting the way my sketches are being rendered.

Here’s a longer example that gets a bit closer to what I’m actually trying to do.

By clicking the mouse I can alter which shape gets drawn first, and this changes the way they are displayed in the sketch, regardless of camera position.  
 ![Screenshot%20from%202018-10-25%2011-44-03](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/aa6df7aabee4b170dbd4bfaa26afac5f1c951d8d.png)

```auto
boolean sphereFirst = true;

void setup() {
  size(1280, 720, P3D);
  hint(ENABLE_DEPTH_TEST);
  hint(ENABLE_DEPTH_SORT);
}

void draw() {
  background(55);
  lights();
  rotateCam();

  // Clicking the mouse button changes which shape gets rendered first.
  if (sphereFirst)
  {
    makesphere();
    makerect();
  }
  else
  {
    makerect();
    makesphere();
  }
}

void rotateCam()
{
  translate(width/2, height/2);
  rotateX(frameCount * 0.002);
  rotateY(frameCount * 0.005);
}

void makerect()
{
  pushMatrix();
  fill(100);
  rotateX(HALF_PI);
  rect(-10, -10, 100, 100);
  popMatrix();
}

void makesphere()
{
  pushMatrix();
  translate(0, -25, 0);
  stroke(50, 255, 50);
  fill(0, 0, 255);
  PShape globe = createShape(SPHERE, 25);
  shape(globe);
  popMatrix();
}

void mousePressed() {
  sphereFirst = !sphereFirst;
}

```

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [October 25, 2018, 6:00am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/11 "2018-10-25T06:00:55Z")

</div>

i see some results regarding tranparency

```auto
void makerect()
{
  pushMatrix();
  stroke(50, 255, 50,mouseY/3);
  fill(100,100,100,mouseX/5);
  rotateX(HALF_PI);
  rect(-10, -10, 100, 100);
  popMatrix();
}

void makesphere()
{
  pushMatrix();
  translate(0, -25, 0);
  stroke(50, 255, 50,mouseY/3);
  fill(0, 255, 255,mouseX/5);
  sphere(25);
  popMatrix();
}

```

the

> hint()

is from processing.js ?? should that work here? well it does not give a error?

//\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
when you use P3D a operation would be nice, here a working example  
for mouse or keyboard

```auto
PImage earth;
PShape globe;

// _________________________________________________________________ SETUP
void setup() {
  size(640, 360, P3D);
  earth = loadImage("earth.jpg");
  globe = createShape(SPHERE, 1);
  globe.setStroke(false);
  globe.setTexture(earth);
  info_print();
}//setup

// _________________________________________________________________ DRAW
void draw() {
  background(0);
  lights(); // everything looks better with lights()
  PTZ();
} // draw 

// _________________________________________________________________ DRAW_OBJECT
void draw_object() { // _________________ called by / from inside PTZ
  noStroke(); //directionalLight(250, 250, 250, 0, 0, -1); //ambientLight(100,100,100); // light and texture not work together
  shape(globe,0, 0);
  sphereAt (3, 0, 0, 0.3, color(140,140,140));
}

// _________________________________________________________________ SPHEREAT
void sphereAt( float x, float y, float z, float r, color colorSphere) {
  translate(x,y,z);
  fill(colorSphere); // fill color of the sphere 
  sphere(r); // size of the sphere
  translate(-x,-y,-z);
}//sphereAt

// _________________________________________________________________
// PTZ tab

int mode = 0;
float Zmag = 21.1;
int Zaxis=-160;                                                       
float Xmag, Ymag = 0;
float newXmag, newYmag = 0; 
int newZmag = 0;
int zoomf = 3;
float newxpos, newypos = 0; // for PAN
float xposd, yposd = 0; // for PAN

// _________________________________________________________________ ROTATE / TILDE and MOVE / PAN
void mousePressed() {
  if (mouseButton == LEFT) { mode=1; } // ORBIT
  else if (mouseButton == RIGHT) { mode=2; } // PAN
  // else if (mouseButton == CENTER) { mode=3; } // zoom mouse wheel
}

// _________________________________________________________________ mouse PT end
void mouseReleased() { 
  mode = 0;
}

// _________________________________________________________________ mouseWheel ZOOM
void mouseWheel(MouseEvent event) {
  int newZmag = event.getCount(); // +- 1
  if (Zmag > 10) { Zmag += newZmag * 5; } else { Zmag += newZmag; } // from 1 to 11 go in step 1 else in step 5 
}

void keyPressed(){
 if ( keyCode == UP ) {Ymag -= 0.1 ;} 
 if ( keyCode == DOWN ) {Ymag += 0.1 ;} 
 if ( keyCode == RIGHT) {Xmag -= 0.1 ;} 
 if ( keyCode == LEFT ) {Xmag += 0.1 ;}
 
 if ( keyCode == 16 ) {Zmag -= 1 ;} // [PageUP]
 if ( keyCode == 11 ) {Zmag += 1 ;} // [PageDOWN]
 //println("key: "+key); println("keyCode: "+keyCode);
 
}
// _________________________________________________________________ Pan Tilde Zoom
void PTZ() {
  pushMatrix(); 
  translate(width/2, height/2, Zaxis);
  // get new mouse operation  
  if ( mode == 2 ) { // PAN ( right mouse button pressed)
    xposd = (mouseX-float(width/2));
    yposd = (mouseY-float(height/2));  
  }  
  newxpos = xposd;// xposd=0;
  newypos = yposd;// yposd = 0; 
  translate(newxpos,newypos, 0); // move object
  if ( mode == 1 ) { // ORBIT ( left mouse button pressed)
  newXmag = mouseX/float(width) * TWO_PI;
  newYmag = mouseY/float(height) * TWO_PI;
  
  float diff = Xmag-newXmag;
  if (abs(diff) > 0.01) { Xmag -= diff/4.0; }
  diff = Ymag-newYmag;
  if (abs(diff) > 0.01) { Ymag -= diff/4.0; }
  }
  rotateX(-Ymag); rotateY(-Xmag);   
  scale(Zmag);
  
  draw_object(); // see MAIN: THE OBJECT
  
  popMatrix();   
}

// _______________________________________________ SETUP PRINT INFO
void info_print() {
 println("PTZ info:");
 println("mouse LEFT press drag up down right left || key arrow UP DOWN RIGHT LEFT -> rotate");
 println("mouse RIGHT press -> move ");
 println("mouse WHEEL turn || key PAGE UP DOWN -> zoom");
}

```

you need the earth image in  
/data/earth.jpg  
 ![earth](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/10e3203cf62a49c77c8aa907de2774e82c4f75c0.jpeg)

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [October 25, 2018, 6:18am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/12 "2018-10-25T06:18:59Z")

</div>

The only thing missing in your program is replacing the two hints by this one

```
hint(DISABLE_DEPTH_TEST);
```

---

<div class="post-metadata">

**Author:** ![garroad\_ran](https://avatars.discourse-cdn.com/v4/letter/g/f08c70/32.png) [@garroad\_ran](https://discourse.processing.org/u/garroad_ran)\
**Post date:** [October 25, 2018, 6:55am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/13 "2018-10-25T06:55:42Z")

</div>

@kll

> the `hint()` is from processing.js ?? should that work here? well it does not give a error?

Yeah, it works fine. It also works fine with @jeremydouglass 's example, so I don’t think it’s only for processing.js.

---

<div class="post-metadata">

**Author:** ![garroad\_ran](https://avatars.discourse-cdn.com/v4/letter/g/f08c70/32.png) [@garroad\_ran](https://discourse.processing.org/u/garroad_ran)\
**Post date:** [October 25, 2018, 6:56am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/14 "2018-10-25T06:56:24Z")

</div>

@hamoid

> The only thing missing in your program is replacing the two hints by this one `hint(DISABLE_DEPTH_TEST);`

I tried that, but it didn’t change anything on my machine. The shape that I draw last is always rendered in front, regardless of how they are actually positioned in the space.

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [October 25, 2018, 8:21am UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/15 "2018-10-25T08:21:13Z")

</div>

Weird… for me with

```
hint(DISABLE_DEPTH_TEST);

```

does sorted-by-code and

```
hint(ENABLE_DEPTH_TEST);

```

does sorted-by-depth.

---

<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:** [October 31, 2018, 6:06pm UTC](https://discourse.processing.org/t/draw-order-in-3d/4789/16 "2018-10-31T18:06:44Z")

</div>

Referring to your makeRect example:

`rect` is a 2D shape. Try `box` instead.

When using rect in 3D space or using box you need to use `translate ()` with 3 parameters.

Without translate it’s at Z = 0 I guess or just drawn above the scene
