Weird frameRate drops precipitously when set at 60 fps or below (P3D)

edited February 2018 in Programming Questions

I'm experiencing a weird effect. When I set the framerate to 120, the actual framerate will hover around 50-65. If I set the framerate to 60, I'll get around 18-24fps. If I set it to 61fps I'll get about 50fps again. If I set the framerate to 30, it might be even slower. What's going on here?

Also, why does drawing a full frame pimage with transparency under a PGraphics object lower the fps from max 100 to 60?

In other words, I have a max fps at a certain resolution of 120fps. I have a drawing function with a fps "cost" of 20fps. If I display the result of that function as a pg.pimage my fps drops another 40fps. Is there any faster way to render pimages?

Basically, I'm forced to set the fps to 120 to get an acceptable framerate, it seems like there is some kind of optimization going on with the renderer which kicks in when the framerate is set to above 60. How do I make sure whatever that optimization is always on, and if possible how do I crank it up?

Tagged:

Answers

  • I haven't taken the time to dig through the frameRate variable and totally understand how it's working. But what I do know is it gets updated each time draw runs to try to match the capabilities of your system. So using frameRate() is kinda like a suggestion for what you want the frameRate to be. You can see what I'm talking about here.

    There are two work arounds I can think of trying. The first is to just put frameRate(120) in draw somewhere. This might help slightly to offset updating the frameRate. This won't break anything but chances are it won't make a big difference.

    The other is to use an @Override method on handleDraw() and remove the lines of code that update frameRate. However I would be hesitant to try this. I have no idea what might happen. I don't know it could work. If I was to guess you might start seeing dropped frames or worst case it blows up entirely.

    The simple fact is some things are expensive and if your computer can't run faster than your out of luck all the work arounds won't help. Your best bet is to, improve your code for performance, get a better computer, or use saveFrame() and let it run slowly then make a video from the frames.

  • edited March 2018

    Do you have a simple test sketch that demonstrates this problem?

    Does your code have an expensive process that doesn't run every frame, but only some frames? frameRate sets a maximum speed for an individual frame, but not a minimum -- so you could have framerate cliffs that get triggered.

    On the other hand, the point in the cycle that you are collecting and measuring frame rates can have a strong impact on the results, even with small delays.

    For example, consider this sketch, which displays the results of frameRate(120):

    int lastFrame;
    int lastMillis;
    int thisFrame;
    int avgFrame;
    void setup() {
      lastMillis = millis();
      frameRate(120);
    }
    void draw() {
      background(0);
      thisFrame = 1000/(1+millis()-lastMillis);
      text("millis:   " + millis() + "\n" +
           "fcount: " + frameCount + "\n" +
           "fps:      " + thisFrame + "\n" +
           "avg:      " + frameCount/(millis()/(float)1000) + "\n",
           10, 20);
      lastMillis = millis();
    }
    

    Now, try adding a delay (e.g. delay(20)) at the beginning of draw, or the end of draw, or amid the thisFrame / lastMillis calculations and the text display. Notice what changes and what doesn't.

    Now try adding a delay that only happens every 2nd frame, or every 4th frame.

    if(frameCount%2==0){
      delay(20);
    }
    

    et cetera

  • using vsync on your monitor might be effecting this. if you've got vsync on and your monitor is doing 60fps but the sketch isn't capable of rendering a frame in that time then you'll get get a frame every two refreshes, or 30fps. would explain the cliffs.

Sign In or Register to comment.