Jump to content

Limit frames per second


ShimShamSam
 Share

Recommended Posts

Hi,

 

 As we're using requestAnimationFrame under the hood, this should be very efficient in the way the browser use GPU ressources. Why would you want to limit to 30 fps? Is there a specific reason for that?

 

 You could modify the render loop inside the babylon.js code to use a setTimeout to 33 ms to simulate a 30 fps render loop. But this is much less elegant & efficient than using requestAnimationFrame.

 

Bye,

 

David

Link to comment
Share on other sites

  • 2 weeks later...

Hi,

 

 As we're using requestAnimationFrame under the hood, this should be very efficient in the way the browser use GPU ressources. Why would you want to limit to 30 fps? Is there a specific reason for that?

 

 You could modify the render loop inside the babylon.js code to use a setTimeout to 33 ms to simulate a 30 fps render loop. But this is much less elegant & efficient than using requestAnimationFrame.

 

Bye,

 

David

 

Followed your advice as Noticed that: 

window.setTimeout(func,16); 

when I change it to 

window.setTimeout(func,60); or window.setTimeout(func,30);

my program runs a lot smoother and faster on Chrome, but legs heavily in IE11

Link to comment
Share on other sites

  • 1 year later...

I'm also interested in limiting the frame rate. I did that before I used babylon.js in cases a high fps wasn't necessary to limit the cpu usage which is especially useful for mobil devices or laptops running on battery. Currenty babylon.js uses way more cpu than for example three.js for the same tasks. Since you don't always need 60fps it would be a nice option.
Never hat any problems with a higher value in window.setTimeout.

Link to comment
Share on other sites

  • 2 years later...

Hi, 

 

sorry to resurrect an old topic but i thought it was relevant, I assume this hasnt been implemented as i cant find an answer?

my reason for needing to alter the FPS is that I have multiple babylon canvas in one window. but some of those canvas are hidden when i click onto a different tab (within my window, not a new browser tab) so if i clicked on a diff tab I would like to lower the fps as its unnecessary to render at 60fps when its not on screen.

hope that makes sense! let me know if i need to put this into a new topic.

 

many thanks

Link to comment
Share on other sites

<!DOCTYPE html>
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
        <script type="text/javascript" src="http://rawgit.com/vitmalina/w2ui/master/dist/w2ui.min.js"></script>
        <script type="text/javascript" src="https://cdn.babylonjs.com/babylon.max.js"></script>
        <link rel="stylesheet" type="text/css" href="http://rawgit.com/vitmalina/w2ui/master/dist/w2ui.min.css" />
    </head>
    <body>

    <div id="previewTabs">
        <div id="tabs" style="width: 100%; height: 29px;"></div>
        
        <div id="tab1" class="tab" style="background-color: #3E0042;">
            <div id="blankTab">
            </div>
        </div>
        
        <div id="tab2" class="tab" style="background-color: #3E0042;">
            <div id="babylonTab">
                <canvas id='babylonCanvas'></canvas>
            </div>
        </div>
        
    </div>

        <script type="text/javascript">
            
            var configPreview = {
                tabs: {
                    name: 'tabs',
                    active: 'tab2',
                    tabs: [
                        { id: 'tab1', caption: 'Blank Tab' },
                        { id: 'tab2', caption: 'Babylon Tab' },
                    ],
                    onClick: function (event) {
                        $("#previewTabs .tab").hide(); // hides all tabs
                        $("#previewTabs #" + event.target).show(); // shows tab of click event.target
                        
                        var allTabs = this.tabs;
                        for(var t = 0; t < allTabs.length; t++){
                            allTabs[t].style = "background-color: white"
                            w2ui.tabs.refresh();
                        }
                        
                        switch(event.tab.caption){
                                
                            case "Babylon Tab":
                                
                                break;
                        }
                    }
                }
            };         

            function setupPreviewTabs() {
                $('#tabs').w2tabs(configPreview.tabs);
                $('#tab2').show();
                $("#tabs").css("height", 28);
                tabsResize()  
            };  
            
            function tabsResize(){ 

                $("#particleBuilderLayout").css("width", "100%")
                $("#particleBuilderLayout").css("height", $("#tabs").height())    
            }


            (function(){
                setupPreviewTabs();
            })();
            
            (function (window, BABYLON) {
                var canvas = document.getElementById("babylonCanvas");

                // Check support    
                if (!BABYLON.Engine.isSupported()) {        
                    window.alert('Browser not supported');    
                } else {       

                    // Babylon        
                    engine = new BABYLON.Engine(canvas, true); 
                    //Creating scene (in "Scene.js")        
                    scene = createScene(engine);        
                    scene.canvas = canvas;
                    scene.activeCamera.attachControl(scene.canvas);  

                    // Once the scene is loaded, just register a render loop to render it        
                    engine.runRenderLoop(function () {            
                        scene.activeCamera.attachControl(scene.canvas);            
                        scene.render();        
                    });        
                } 
            }(window, BABYLON)); 
            
            function createScene(engine) {
                //console.log("CREATING SCENE")
                // Create the scene space
                var scene = new BABYLON.Scene(engine);
                scene.clearColor = new BABYLON.Color4(0.243137, 0.0, 0.258823, 1.0);
                //console.log("CREATING CAMS");
                // Add a camera to the scene and attach it to the canvas
                scene.perspectiveCamera = new BABYLON.ArcRotateCamera("PerspectiveCamera", Math.PI * 1.5, Math.PI / 2, 2, BABYLON.Vector3.Zero(), scene);

                scene.perspectiveCamera.minZ = 0.01;
                scene.perspectiveCamera.maxZ = 10000;

                //console.log("MAKING OBJECTS");
                //-----OBJECTS-----
                // Add and manipulate meshes in the scene
                scene.emitterParent = BABYLON.MeshBuilder.CreateBox("box", {width: 0.1, height: 0.1, depth: 0.1}, scene);


                var emitterParentMat = new BABYLON.StandardMaterial("particleEmitterMat", scene);
                emitterParentMat.wireframe = true;
                emitterParentMat.disableLighting = true;
                scene.emitterParent.material = emitterParentMat;


                var ground = BABYLON.Mesh.CreatePlane("ground", 50.0, scene);
                ground.position = new BABYLON.Vector3(0, -10, 0);
                ground.rotation = new BABYLON.Vector3(Math.PI / 2, 0, 0);

                ground.material = new BABYLON.StandardMaterial("groundMat", scene);
                ground.material.backFaceCulling = false;
                ground.material.diffuseColor = new BABYLON.Color3(0.3, 0.3, 1);

                //console.log("SETTING LIGHTS");
                //-----LIGHTING-----
                // Add lights to the scene            
                scene.light1 = new BABYLON.PointLight("light1", new BABYLON.Vector3(-1, 0, 0), scene);

                //set light to be at same position as dummy sphere and set parent
                scene.light1.position = new BABYLON.Vector3(-1, 0, 0)     

                //console.log("SET ACTIVE CAM");
                scene.activeCamera = scene.perspectiveCamera;  
                
                // Fountain object
                var fountain = BABYLON.Mesh.CreateBox("foutain", 1.0, scene);
                
                // Create a particle system
                var particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);

                //Texture of each particle
                particleSystem.particleTexture = new BABYLON.Texture("https://raw.githubusercontent.com/BabylonJS/Babylon.js/master/Playground/textures/flare.png", scene);

                // Where the particles come from
                particleSystem.emitter = fountain; // the starting object, the emitter
                particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0); // Starting all from
                particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0); // To...

                // Colors of all particles
                particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
                particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
                particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);

                // Size of each particle (random between...
                particleSystem.minSize = 0.1;
                particleSystem.maxSize = 0.5;

                // Life time of each particle (random between...
                particleSystem.minLifeTime = 0.3;
                particleSystem.maxLifeTime = 1.5;

                // Emission rate
                particleSystem.emitRate = 1500;

                // Blend mode : BLENDMODE_ONEONE, or BLENDMODE_STANDARD
                particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;

                // Set the gravity of all particles
                particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);

                // Direction of each particle after it has been emitted
                particleSystem.direction1 = new BABYLON.Vector3(-7, 8, 3);
                particleSystem.direction2 = new BABYLON.Vector3(7, 8, -3);

                // Angular speed, in radians
                particleSystem.minAngularSpeed = 0;
                particleSystem.maxAngularSpeed = Math.PI;

                // Speed
                particleSystem.minEmitPower = 1;
                particleSystem.maxEmitPower = 3;
                particleSystem.updateSpeed = 0.005;

                // Start the particle system
                particleSystem.start();

                console.log("LOADING scene");
                return scene;

            };

            
        </script>

    </body>
</html>

 

Link to comment
Share on other sites

Here is a simplified version in a playground, using a GUI rather than tab switching, showing that engine.stopRenderLoop() does work but with issues https://www.babylonjs-playground.com/#ZMDY27

Issues

  1. Does not stop on first click of Stop button but click again and the stop - start works.
  2. Needs the setTimeout to work, maybe because in the playground (or maybe not)
  3. When re-starts it goes from the initial setup not a continuation.

This is about as far as I can help you now need someone who knows the engine better than I.

Link to comment
Share on other sites

ok thanks for this, perhaps the double stop was why i didnt get it to work either ( i only spend 5 seconds trying haha) 

maybe someone could code in the ability to change fps, there is definitly a need for it. Adobe Animate allows you to do it which I have used multiple times for example if you are creating a book like website and have animations on each page you can change fps to 0 when you change page as pausing the animation still creates frames. same case would apply to babylon

thanks again for your help John. hopefully one of the top dogs see's this! 

Link to comment
Share on other sites

I think all you need is:

scene.render()

Those engine-related functions are handy for the babylon playground, but not strictly needed.

Calling scene.render() in a window.requestAnimationFrame() will render at the refresh rate of the target display and automatically pauses when the browser loses focus (both a good thing and a bad thing).  Just having a custom check like if (!paused) { scene.render() } can make your own pause feature.

setInterval and setTimeout are viable too, but if used in the playground they will produce some bugs... but that's just in the playground, they'll work fine elsewhere

There are tons of ways to make loops, but uhm here's one:

window.onload = function() {

    let previous = performance.now()

    const loop = function() {
        window.requestAnimationFrame(loop) // queue next frame
        const now = performance.now()
        const delta = (now - previous) / 1000
        previous = now
      
        if (!paused) {
            gameLogicStuff(delta)
            scene.render()
        }

    }

    // starts the loop
    loop()
}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...