# 2 sided transparency

**URL:** <https://discourse.processing.org/t/2-sided-transparency/2471>\
**Category:** Coding Questions\
**Created:** [August 8, 2018, 10:35am UTC](https://discourse.processing.org/t/2-sided-transparency/2471 "2018-08-08T10:35:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![filarius](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/filarius/32/1053_2.png) [@filarius](https://discourse.processing.org/u/filarius)\
**Post date:** [August 8, 2018, 10:35am UTC](https://discourse.processing.org/t/2-sided-transparency/2471/1 "2018-08-08T10:35:07Z")

</div>

I want to make dynamic visualization where I need to use cube made of as many as possible smaller cubes with controlled color and opacity.  
It will be somekind of voxel cloud.  
I’m new to Processing but I have some knowladge about graphics.

As first steps to my goal I trying to make cubes manually.  
I use **beginShape(QUADS);** and **fill()** to make transparent cube, but I found what opacity works not as I expect.  
I see what opacity is like works only in one direction, and not transparent at all in another direction.  
How to fix that?  
there is my sketch

```auto
float a;
int c = 200 + 255*255+ 120*256*256 ;
boolean toggle = true;
void setup() {
  size(640, 640, P3D);
  textMode(MODEL);
  //noStroke();
//fill(255,000,00,100);
}

void randfill()
{
 int x = int(random(255));
 int y = int(random(255));
 int z = int(random(255));
 fill(x,y,z,40);
}

void draw() {
  background(190);
  //lights();

  
  translate(width/2, height/2, 0);
  rotateX(-PI/8+a/17); 
  rotateY(PI/6+a/23);
  rotateZ(PI/9);
  stroke(0);  
  fill(0);
  
  text(" 1 1 1", 100, 100, 100);
  text("-1 1 1",-100, 100, 100);
  text("-1 -1 1",-100,-100, 100);
  text("-1 -1 -1",-100,-100,-100);
  text("-1 1 -1",-100, 100,-100);
  text(" 1 -1 -1", 100,-100,-100);
  text(" 1 1 -1", 100, 100,-100);

  if (toggle){
    a += 0.05;
  }
  if(mousePressed){
    toggle = !toggle;
  }
    
  beginShape(QUADS);
  randfill();
  vertex(100,100,100);
  vertex(-100,100,100);
  vertex(-100,100,-100);
  vertex(100,100,-100); 
  
  randfill();
  vertex(100,-100,-100); 
  vertex(100,100,-100);
  vertex(100,100,100);
  vertex(100,-100,100);
  
  randfill();
  vertex(-100,-100,100);
  vertex(-100,100,100);
  vertex(100,100,100);
  vertex(100,-100,100); 
  
  randfill();
  vertex(-100,-100,100);
  vertex(-100,-100,-100);
  vertex(-100,100,-100);
  vertex(-100,100,100);
  
  randfill();
  vertex(-100,-100,100);
  vertex(100,-100,100);
  vertex(100,-100,-100);
  vertex(-100,-100,-100);
 
  randfill();
  vertex(-100,-100,-100);
  vertex(-100,100,-100);
  vertex(100,100,-100);
  vertex(100,-100,-100);  
  
  fill(0,250);
  vertex(100,200,100);
  vertex(-100,200,100);
  vertex(-100,200,-100);
  vertex(100,200,-100);
  
  vertex(200,-100,-100); 
  vertex(200,100,-100);
  vertex(200,100,100);
  vertex(200,-100,100);

  vertex(-100,-100,200);
  vertex(-100,100,200);
  vertex(100,100,200);
  vertex(100,-100,200); 

  vertex(-200,-100,100);
  vertex(-200,-100,-100);
  vertex(-200,100,-100);
  vertex(-200,100,100);  

  vertex(-100,-200,100);
  vertex(100,-200,100);
  vertex(100,-200,-100);
  vertex(-100,-200,-100); 

  vertex(-100,-100,-200);
  vertex(-100,100,-200);
  vertex(100,100,-200);
  vertex(100,-100,-200); 
  
  endShape();
  text(" 1 1 1", 100, 100, 100);
  text("-1 1 1",-100, 100, 100);
  text("-1 -1 1",-100,-100, 100);
  text("-1 -1 -1",-100,-100,-100);
  text("-1 1 -1",-100, 100,-100);
  text(" 1 -1 -1", 100,-100,-100);
  text(" 1 1 -1", 100, 100,-100);
  //box(160); 
}

```

 ![2018-08-08_13-37-01](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/dc5f6413d85f0e9c5253aae26ef0bbcc8a5233bd.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:** [August 8, 2018, 10:57am UTC](https://discourse.processing.org/t/2-sided-transparency/2471/2 "2018-08-08T10:57:35Z")

</div>

Does it look closer to what you want if you throw a

```
hint(ENABLE_DEPTH_SORT);

```

at the end of setup?

---

<div class="post-metadata">

**Author:** ![filarius](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/filarius/32/1053_2.png) [@filarius](https://discourse.processing.org/u/filarius)\
**Post date:** [August 8, 2018, 11:26am UTC](https://discourse.processing.org/t/2-sided-transparency/2471/3 "2018-08-08T11:26:29Z")

</div>

> [@hamoid](#):
>
> Does it look closer to what you want if you throw a
> 
> ```auto
> hint(ENABLE_DEPTH_SORT);
> 
> ```
> 
> at the end of setup?

Yes, its looks like what I want.  
I think i got how its works, but its pretty surpricing for me.

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [August 8, 2018, 12:00pm UTC](https://discourse.processing.org/t/2-sided-transparency/2471/4 "2018-08-08T12:00:59Z")

</div>

You could also try

```auto
hint(DISABLE_DEPTH_CHECK);

```

Somewhat different output - depends what effect you want the opacity to have. Massively different CPU usage though.

---

<div class="post-metadata">

**Author:** ![filarius](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/filarius/32/1053_2.png) [@filarius](https://discourse.processing.org/u/filarius)\
**Post date:** [August 8, 2018, 9:57pm UTC](https://discourse.processing.org/t/2-sided-transparency/2471/5 "2018-08-08T21:57:33Z")

</div>

i’m not sure if I undertanding it right, but is here possible more speed-up ?  
I add pre-sorting of faces adding order to NOT use **hint(ENABLE\_DEPTH\_SORT)** because its really slow.  
Also instead of adding all 6 faces of cube I add only 3 faces and will limit camera rotation to see cubes only from “good” side - side where this 3 faces will be viewed only from front side.  
**hint(DISABLE\_DEPTH\_TEST);** do not make much change in FPS, and right now I can not say if rendering result is affected.

This changes made resonable performance for rendering 30^3 - 40^3 cubes

this is my sketch

```auto

int ar_size = 30;// number of cubes is ar_size^3
float cube_scale = 600; //hardcoded scaling

int q[][] = new int[ar_size* ar_size*ar_size][3];
void setup() {
  size(640, 640, P3D);
  textMode(MODEL);
  //hint(ENABLE_DEPTH_SORT);
  //hint(DISABLE_DEPTH_TEST);
  noStroke();
//fill(255,000,00,100);
for(int i=0;i<ar_size* ar_size*ar_size;i++){
   int x = i;
   q[i][0] = x % ar_size;
   x /= ar_size;
   q[i][1] = x % ar_size;
   x /= ar_size;
   q[i][2] = x;
}
//bubble sort of cubes inserting order
for(int i=0; i<ar_size*ar_size*ar_size-1; i++){
  for(int j=i+1; j<ar_size*ar_size*ar_size; j++){
    int s1 = q[i][0]+q[i][1]+q[i][2];
    int s2 = q[j][0]+q[j][1]+q[j][2];
    if(s1<s2){
      int t1 = q[i][0];
      int t2 = q[i][1];
      int t3 = q[i][2];
      q[i][0]=q[j][0];
      q[i][1]=q[j][1];
      q[i][2]=q[j][2];
      q[j][0]=t1;
      q[j][1]=t2;
      q[j][2]=t3;
    }
  }
}
}

void randfill(int p)
{
 int x = int(0);
 int y = int(0);
 int z = int(random(100));
 fill(x,y,z,p); 
}

//place cube
void bx(float x,float y,float z,float size)
{
 // randfill(10);
 /*
  vertex(x+size,y-size,z-size); 
  vertex(x+size,y+size,z-size);
  vertex(x+size,y+size,z+size);
  vertex(x+size,y-size,z+size);

  //randfill(10);
  vertex(x-size,y-size,z+size);
  vertex(x-size,y+size,z+size);
  vertex(x+size,y+size,z+size);
  vertex(x+size,y-size,z+size);
  

    //randfill(10);
  vertex(x+size,y+size,z+size);
  vertex(x-size,y+size,z+size);
  vertex(x-size,y+size,z-size);
  vertex(x+size,y+size,z-size);
  */
  
   // randfill(10);
  vertex(x-size,y-size,z-size);
  vertex(x-size,y+size,z-size);
  vertex(x+size,y+size,z-size);
  vertex(x+size,y-size,z-size); 
   
    //randfill(10);
  vertex(x-size,y-size,z+size);
  vertex(x+size,y-size,z+size);
  vertex(x+size,y-size,z-size);
  vertex(x-size,y-size,z-size);
  
    //randfill(10);
  vertex(x-size,y-size,z+size);
  vertex(x-size,y-size,z-size);
  vertex(x-size,y+size,z-size);
  vertex(x-size,y+size,z+size);
}

void draw() {
  println("fps: ",frameRate);
  background(0);
  //lights();
  colorMode(HSB,100,100,100,1024);

  translate(width/2, height/2, 0);
  rotateX(0.05*210*PI/8 + (mouseY-height/2)*0.003);  
  rotateY(0.05*285*PI/8 + (mouseX-width/2)*0.003);
  
  beginShape(QUADS);
  noStroke();
  
  float size = cube_scale/(2*ar_size);
  
  for(int i=0;i<ar_size*ar_size*ar_size;i++){
    int ind = q[i][0]+q[i][1]+q[i][2];
    int op = 10*(ar_size/2 - ind/3); 
    float r = abs(q[i][0]-ar_size/2)+
              abs(q[i][1]-ar_size/2)+
              abs(q[i][2]-ar_size/2);
    r = (ar_size*1.4-r)/ar_size;
    op = int(r*40);
    randfill(op);
    bx(q[i][0]*size-size*ar_size/2,
       q[i][1]*size-size*ar_size/2,
       q[i][2]*size-size*ar_size/2,
       size/2);
  } 
  endShape();  
}

```

 ![java_2018-08-07_00-58-40](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/ed128518f6adf3ccae46e03e644d5c050148b802.jpeg)

On my hardware I have ~6 FPS for 40^3 cubes.  
Any tips to make sketch even faster?

---

<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:** [August 8, 2018, 11:07pm UTC](https://discourse.processing.org/t/2-sided-transparency/2471/6 "2018-08-08T23:07:15Z")

</div>

27000 is a lot of cubes! 🙂

Calling vertex 12\*27000 times is not ideal. I think that sends a lot of data to the GPU item by item on each frame. Faster is probably having one PShape that contains all the quads to batch the GPU operations, then draw it in one `shape(myShape)` operation. Try to update the PShape (moving it’s vertices) instead of deleting and creating new PShapes. I think that should help, but getting to 60 fps may be a challenge and require lower level stuff like direct openGL or C++.

I wonder if avoiding transparency and using `blendMode(ADD)` instead helps, although it would look different.

---

<div class="post-metadata">

**Author:** ![filarius](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/filarius/32/1053_2.png) [@filarius](https://discourse.processing.org/u/filarius)\
**Post date:** [August 9, 2018, 12:24am UTC](https://discourse.processing.org/t/2-sided-transparency/2471/7 "2018-08-09T00:24:58Z")

</div>

> Try to update the PShape (moving it’s vertices) instead of deleting and creating new PShapes.

I do not undertand because I do not use PShape class and just use pure beginShape()

BTW your reply made me try.  
this is about 8.2 FPS for 40^3 cubes

```auto
  for( iterating cubes ){  
 beginShape(QUADS);
    //add 3 faces of cube
 endShape();
  } 

```

And this is 5.5 FPS

```auto
 beginShape(QUADS);
  for( iterating cubes ){ 
    
  }
 endShape();

```

meanwhile choosing right bulk size also can be a little faster as 8.5 FPS

```auto
  int cnt = -1;
  for( iterating cubes ){
    cnt += 1;
    if(cnt==0) {beginShape(QUADS);}
    // add 3 faces of cube 
    if(cnt==999){
      cnt=-1;
      endShape();      
    }  
  }

```

I’m not sure if I undertand you right, but by my thoughts using examples from  
[https://www.processing.org/reference/createShape\_.html](https://www.processing.org/reference/createShape_.html)  
must not do big difference in perfomance between using PShape class or just beginShape() / endShape() in draw(), but I can try to check it.

P.S. I do not need actually 60 FPS, but I want to make it as fast as possible to be able to have more cubes with not that low FPS, and also I will need to add array processing at each frame, what also will drop FPS.

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [August 9, 2018, 5:04am UTC](https://discourse.processing.org/t/2-sided-transparency/2471/8 "2018-08-09T05:04:45Z")

</div>

> [@filarius](#):
>
> my thoughts using examples from  
> [createShape() / Reference / Processing.org](https://www.processing.org/reference/createShape_.html)  
> must not do big difference in perfomance between using PShape class or just beginShape() / endShape() in draw(), but I can try to check it.

There’s a massive difference. In the examples under Demo/Performance compare CubicGridImmediate with CubicGridRetained.

Unfortunately, updating the geometry seems to have a bottleneck - at least the results with the particles examples are the opposite for me. Not looked enough to work out why yet.

---

<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:** [August 9, 2018, 10:56am UTC](https://discourse.processing.org/t/2-sided-transparency/2471/9 "2018-08-09T10:56:55Z")

</div>

> [@filarius](#):
>
> I do not undertand because I do not use PShape class and just use pure beginShape()

I was getting ahead of myself. My point was that if you switch to using a PShape, recreating it on every frame may be worse than modifying an existing instance.

The question was about 2 sided transparency and I think now you have some ideas on how to do that. To make it easier to find by others, maybe open a new question about increasing frame rate when generating 3D graphics?

Spoiler: frame rate can be limited by different reasons: high CPU usage, high GPU usage (shader complexity or high number of vertices or pixels), amount of data sent from CPU to GPU, computer temperature, etc. Drawing 27.000 shapes is actually a low number, and calculating 27.000 operations on the CPU is also a very low number. But sending data elements one by one from the CPU to the GPU is slow. Sending less, bigger chunks of data to the GPU, or keeping data in the GPU you can achieve better results. But let’s continue in another thread 🙂
