hint(ENABLE_DEPTH_SORT) issues

working on a P3D sketch with many semi-transparent, moving geometries distributed in space. finding transparency renders as desired on when i use

hint(ENABLE_DEPTH_SORT);

however, there seems to be some kind of buffering issue interfering with the sketch executing. after a certain number of frames the rendering progressively slows down, eventually grinding to a stop, and a lot of nasty looking triangular artifacts start flickering on the geometries. any ideas what i can do to alleviate this issue?

here’s the full code:

PGraphics img;
int[][] crystals;

int number = 5000;
int radius = 220;
int depth = 40;

int xRange = 20000;
int yRange = 7000;
int zRange = 17000;

float camPosX = 4000;
float camPosY = 2500;
float camPosZ = 5000;
float camSpeedZ = 7.0;
float cameraZ;

float wobbleDriver = 0;
float wobbleSpeed = 0.07;
float maxWobble = 10;

int cAlph = 50;
float cSat = 50.0;

void setup(){
  size(1920, 1080, P3D);
  cameraZ = (height/2.0) / tan(PI*60.0/360.0);
  img = createGraphics(1920, 1080, P3D);
  img.smooth(4);
  img.hint(ENABLE_DEPTH_SORT);
  randomSeed(0);
  
  crystals = new int[number][6];
  for(int x=0; x < number; x++ ){
    crystals[x][0] = int(random(xRange));
    crystals[x][1] = int(random(yRange));
    crystals[x][2] = int(random(zRange));
    crystals[x][3] = int(random(20, radius));
    crystals[x][4] = int(random(20, depth));
    crystals[x][5] = int(random(1, maxWobble));
  }
}

void draw(){
  background(0, 0);
  img.beginDraw();
  img.colorMode(HSB, 100);
  img.camera(camPosX, camPosY, camPosZ, camPosX, camPosY + 300, -4000, 0, 1, 0);
  img.perspective(PI/3.0, width/height, cameraZ/10.0, cameraZ*100.0);
  img.background(0, 0);
  
  for(int x = 0; x < number; x++) {
    int crystalColor = 100 - int(map(crystals[x][1], 0, yRange, 0, 100));
    img.fill(crystalColor, cSat, 100, cAlph);
    
    img.pushMatrix();
    img.translate(crystals[x][0] - (width), crystals[x][1] - (height), -crystals[x][2] + (zRange /4));
    
    float angle = 0;
    float angleIncrement = TWO_PI / 6;
    
    img.rotateX(radians(cos(wobbleDriver) * crystals[x][5]));
    img.rotateZ(radians(sin(wobbleDriver) * crystals[x][5]));
    img.rotateY(radians(sin(wobbleDriver) * crystals[x][5]));
  
    img.beginShape(QUAD_STRIP);
    img.stroke(0);
    for (int i = 0; i < 6 + 1; ++i) {
      img.vertex(crystals[x][3]*cos(angle), 0 - crystals[x][4]/2, crystals[x][3]*sin(angle));
      img.vertex(crystals[x][3]*cos(angle), crystals[x][4]/2, crystals[x][3]*sin(angle));
      angle += angleIncrement;
    }
    img.endShape();
  
    // top cap
    angle = 0;
    img.beginShape();
    img.noStroke();
    img.vertex(0, 0 - crystals[x][4]/2, 0);
    for (int i = 0; i < 6 + 1; i++) {
      img.vertex(crystals[x][3] * cos(angle), 0 - crystals[x][4]/2, crystals[x][3] * sin(angle));
      angle += angleIncrement;
    }
    img.endShape();
    
    // bottom cap
    angle = 0;
    img.beginShape(TRIANGLE_FAN);
    img.vertex(0, crystals[x][4]/2, 0);
    for (int i = 0; i < 6 + 1; i++) {
      img.vertex(crystals[x][3] * cos(angle), crystals[x][4]/2, crystals[x][3] * sin(angle));
      angle += angleIncrement;
    }
    img.endShape();
    
    img.popMatrix();
  }
  img.endDraw();
  image(img, 0, 0);
  //img.save("wobbl_SP_" + nf(frameCount, 3) + ".png");
  
  camPosZ -= camSpeedZ;
  wobbleDriver += wobbleSpeed;
  
  if(frameCount > 750){ stop(); }
}

A while back @hamoid shared a piece of code that combines several types of hint: Program to test hint() with transparency. Maybe there is something in there which works better for your sketch.

Your performance issue can likely be improved by optimizing your code. If you manage to figure out where your sketch is having a hard time, you could try to do more in-depth research how to improve these parts. There is a nice guide on https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance that explains possible methods. It’s for P5 sketches, but the same principles can be applied on your Processing Java sketch.

1 Like

Thanks Tiemen, appreciate the suggestions. Those interesting links offer useful insight into what various hint() settings do, the optimization link will take some time to fully digest and implement. Whatever the issue it seems to involve some kind of buffer because the sketch runs fine at first but after maybe 30 frames begins to progressively slow down and show increasing numbers of artifacts, eventually grinding to a halt.

One thing I did notice troubleshooting = the issue doesn’t seem related to the number of objects being rendered. Even if I greatly reduce the geometry I’m asking the sketch to draw it still slows down and stumbles at the same point.

Unfortunately under a time constraint with this project so I think abandoning transparency and just going with fully opaque fills regrettably seems the best course for me at this point.

Taking a quick look at your code I can already guess what the issue is. What happens is that you keep redrawing shapes over and over in void draw, even though they visually don’t seem to change.

What might solve your issue is when you create the shapes in void setup beforehand and save them as PShapes. Inside void draw you could retrieve this saved shape; compared to rebuilding each shape again in each loop this will likely massively increase the performance of your sketch.

Hopefully you’ll have enough time to test and implement it. Best of luck!

1 Like

Great tip / suggestion, I will definitely try it and see if that brings improvement, thank you!