Non-realtime Rendering - Performance Workaround

edited March 2017 in How To...

Is there a way to render frames of an animation without outputting to the screen to get around performance issues?

saveFrame itself slows down the performance of sketches so for more complicated animations, the image sequence itself isn't smooth.

Is anyone doing non-realtime rendering?

If not, how are people achieving smooth hd animations?

Screen capture could work but this prevents rendering image sequences with transparent backgrounds

Tagged:

Answers

  • To do non-realtime rendering, simply replace all calls to millis() with Millis()

    long Millis()
    {
      return frameCount*1000.0/YOUR_TARGET_FRAMERATE;
    }
    
    

    This will make the animation run at the speed of saveFrame(). I assume you are using millis() to time your animations.

  • I don't understand fully. Does this Millis() code overwrite a function? It looks like some kind of markup language..

    I'm not using millis() to do the animation currently..

  • That was an error either on the user's part, or caused by this forum software. It should've been -

    long Millis()
    {
      return frameCount*1000.0/YOUR_TARGET_FRAMERATE;
    }  
    

    (I am neither supporting nor criticising @processingRGB's answer)

  • On my part, when you're using non-realtime rendering, I don't think performance is much thought about, most people wouldn't bother as long as the you can push out about a thousand frames an hour (really complex animations - I believe that's the speed for most computer animated films). And yes, now I support @processingRGB's answer. If you rely on millis() with such low frame rates, the animation wouldn't be smooth.

  • And another question - how did you manage to create animations without using millis()? Or perhaps more correctly, how can such an animation be affected by the frameRate?

  • Use frameCount instead of millis. Frame 4 is frame 4 regardless of how long it took to render frames 1, 2 or 3.

    Of course this excludes you from any interaction with the sketch, but you haven't said you need that.

    If you need interaction, or syncing to video or audio then a two stage process might be better - render a low quality version in real time, capturing all the relevant input along with a framed number or timestamp, then read this data in a high quality, non-interactive, non-real-time sketch.

  • edited March 2017

    frameCount.. ok. I've been animations just using the draw() function and putting saveFrame() inside there. When using saveFrame the animation outputted to files isn't smooth.

    Or even without using saveFrame, cpu intensive sketches don't run smoothly. They need to be rendered offline somehow.

    I'm still a bit confused though - are you using frameCount to manual step through the frame. eg.

    int frame;
    
    void setup()
    {
      size(200,200);
      frame = 1;
    }
    
    void draw()
    {
      println(frameCount);
    
      println("Create image - do stuff");
    
      //save image to file
    
      frame += 1;
    
      frameCount = frame;
    }
    

    If anyone has any code which is implementing a non-realtime render, please post.

    I think I'm missing something really simple here as everyone seems to be able to do it but I've not found any code demonstrating it

  • frameCount is a Processing variable. See here - https://processing.org/reference/frameCount.html

  • Too much println in a draw loop can break processing, something to do with the console.

    Yes, framecount is built in.

    When saving frames and making an animation out of them it doesn't matter that the animation on screen is choppy - the output is the frames. You'll later stitch the frames together using ffmpeg or something and the result will be smooth.

  • edited March 2017

    Right. But the frameCount just increases by 1 each time draw is called and the image is created.

    60 images are produced by this sketch but when they are turned into a movie file (using MovieMaker), all the movement in the animation is lost.

    Are people creating each frame manually outside of draw and then adding 1 to the framecount after each saveFrame call ?

    PShader basicShader;
    
    void setup()
    {
      size(1280,720, P3D);
      frameRate(30);
      basicShader = loadShader("fragNoise.glsl");
      basicShader.set("u_resolution", float(width), float(height));
    
    }
    
    void draw(){
      basicShader.set("u_time", millis() / 100.0);  
      shader(basicShader); 
      rect(0,0,width,height);
    
    
      saveFrame("noise-######.png");
    
      println(frameCount);
    
      if(frameCount == 60)
      {
       exit(); 
      }    
    }
    
  • Framecount is built in, you don't need to define or increment it.

    And your sketch uses millis, not framecount in line 13.

  • And you just told us that you never used millis() in your sketch. [-X

    I'm not using millis() to do the animation currently..

  • Is passing millis() to the shader the issue?

    I'm not using millis() to time that animation I meant but should I remove it ?

    Apologies for the confusion. I need to understand more about this as I still really don't understand how frameCount and millis() can be used to time or not time an animation or interact with how a sketch runs in realtime or not...

    If I find or write any code which does this, I'll post it here...

  • if you have a car going from a to b in 10 seconds then you could calculate the position each time using either millis() or framecount.

    with millis can check the current value of millis and draw it at the correct position for that value. for instance, millis = 1000 you know you are 10th of the way. but if each frame takes 2000 millis to render you end up with only 5 frames. worse still, if each frame takes a different time to render then the movement will be jittery.

    if you use frameCount then you know that 10 seconds at 50 frames per second is 500 frames. so each frame you move a 500th of the distance. it doesn't matter how long it takes to render the frame because the resultant frames will be correct.

  • Is passing millis() to the shader the issue?

    Yes

    basicShader.set("u_time", millis() / 100.0);

    Use

    basicShader.set("u_time", frameCount / some float);

    Also setting frameRate(); won't have any effect rather than giving the computer "some time to breathe" if set to a very low number.
    Also since you're constantly writing to disk your harddrive may be a bottleneck, but just for speed ofcourse, won't affect the end result.
    What's causing the jittering is millis as koogs said.

  • Ah ok, thanks for your patience in clarifying this.

Sign In or Register to comment.