Comparatif  Three.js vs. Babylon.js


Sommaire :

1) Code minimum
2) Initialise le moteur de rendu
3) Scènes
4) Fixe la couleur du fond
5) Caméras
6) Animation : animate() / renderLoop()
7) Rendus
8) Redimensionnement automatique du canvas
9) Plein écran
10) Affichage du nombre de FPS (Frames Per Second)
11) Ajout du panneau de contrôle (BJS uniquement)


Dernière MAJ : 11/03/2015

1) Code minimum

Pour 3JS et BJS :

<html>
    <head>
        <title>Title</title>        
        <style>body { background-color: #f0f0f0; margin: 0px; }</style>
    </head>
 
    <body>  
        <div id="container">

               <canvas id="canvas" style="width: 100%; height: 100%"></canvas>

        </div>
 
        // Votre JavaScript ici.
 
    </body>
</html>

 

Le style du canvas (largeur et hauteur à 100%) est utile pour BJS.

 

Utilisation - Librairies JS :

3JS

<script src="three.min.js"></script>
<script src="Detector.js"></script>

BJS

<script src="babylon.2.0.js"></script>
 

 

Votre  JavaScript :

3JS

var canvas, scene, camera;
var renderer;
 
if ( Detector.webgl ) {
    init();
    animate();
}
else window.alert('Could not initialise WebGL, sorry !');
 
 
function init() {
    // init function
}
 
function animate() {
    // animate function
}

BJS

var canvas, scene, camera;
var engine;
 
if ( BABYLON.Engine.isSupported() ) {           
    init();
    renderLoop();
}
else window.alert('Could not initialise WebGL, sorry !');
 
 
function init() {
    // init function
}
 
function renderLoop() {
    // renderLoop function
}

3JS utilise une librairie externe pour la détection du support de WebGL alors que BJS l’intègre nativement.

L’ensemble de l’initialisation de la scène et de ses objets se trouveront dans la fonction init(), leurs animations se trouveront respectivement dans animate() et renderLoop() pour 3JS et BJS.

 

2) Initialise le moteur de rendu

Dans init() :

3JS

canvas = document.getElementById("canvas");
renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true });
renderer.setSize( window.innerWidth, window.innerHeight );
// useless if width and height canvas's attributes are defined  
// but necessary if you want 100% window size with window.innerWidth and window.innerHeight 
 
renderer.setPixelRatio( window.devicePixelRatio );  
// to keep same scale, dimensions ratio on mobile device  

BJS

canvas = document.getElementById("canvas");
engine = new BABYLON.Engine(canvas, true);
 

// engine.setSize( window.innerWidth, window.innerHeight );

// useless if width and height canvas's attributes are defined 

// useless you want 100% window size and that you use canvas's style attribute : style="width: 100%; height: 100%"

 
 
 

Il n’y a pas besoin d’appliquer setPixelRatio avec BJS car celui-ci gère automatiquement l’échelle des dimensions sur appareils mobiles, qui généralement ont un nombre de DPI (=PPP) plus élevé que les écrans d’ordinateurs.

Il n’y a pas besoin d’utiliser setSize avec BJS, cela est également géré automatiquement, utile si l’on souhaite un affichage à 100% des tailles de la fenêtre.

Le second argument optionnel de BABYLON.Engine passé à true indique le support de l’anti-aliasing. Cela correspond au paramètre optionnel antialias de 3JS.

 

3) Scenes

Dans init() :

3JS

scene = new THREE.Scene();

BJS

scene = new BABYLON.Scene(engine);

 

4) Fixe la couleur du fond

Dans init() :

3JS

renderer.setClearColor( 0xf0f0f0 );

BJS

scene.clearColor = new BABYLON.Color3.FromInts(240, 240, 240);

3JS applique la couleur du fond sur le moteur de rendu alors que BJS l’applique sur une scène.

3JS utilise les couleurs avec leur valeur hexadécimale, code RVB décimal, code RVB pourcentage.

Alors que BJS utilise uniquement le code RVB décimal et le code RVB pourcentage.

 

Exemples 3JS :

var color = new THREE.Color( 0xf0f0f0 );
var color = new THREE.Color( "rgb(240,240,240)" );
var color = new THREE.Color( "rgb(94.1%,94.1%,94.1%)" );
var color = new THREE.Color( 94.1, 94.1, 94.1 );
var color = new THREE.Color( "#f0f0f0" );
var color = new THREE.Color( "blue" );
 
renderer.setClearColor( 0xf0f0f0 );
renderer.setClearColor( "rgb(240,240,240)" );
renderer.setClearColor( "#f0f0f0" );
renderer.setClearColor( "blue" );
 
renderer.setClearColor( color );
 

 

Exemples BJS :

scene.clearColor = new BABYLON.Color3.FromInts( 240, 240, 240 );
scene.clearColor = new BABYLON.Color3( 94.1, 94.1, 94.1 );
scene.clearColor = BABYLON.Color3.Blue();
 


5) Caméras

Dans init() :

3JS

camera = new THREE.PerspectiveCamera(45, canvas.width / canvas.height, 0.1, 10000 );
// Champ de vision vertical (focal), 75° pour une vision humaine
// On ne verra pas les objets plus proches que 0.1 et plus loin que 10000
camera.position.set(x, y, z);
//scene.add(camera); // useless
 
camera.lookAt( new THREE.Vector3(x, y, z) );
 

BJS

camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(x, y, z), scene);    
// camera.fov = 45; // useless : 45 by default
// camera.minZ = 0.1;
// camera.maxZ = 10000;
 
 
 
 
camera.setTarget( new BABYLON.Vector3(x, y, z) );
 

L’équivalent de la PerspectiveCamera de 3JS est la FreeCamera de BJS.

Remarque : sous BJS, on peut utiliser STATIC BABYLON.Vector3.Zero()

 

Une différence notable entre ces 2 librairies se situe au niveau de la scène :

BJS attache la caméra à une scène.

Ainsi pour une animation avec Babylon, il suffira d’appeler la méthode render sur la scène.

Alors qu’avec ThreeJS, il faudra appeler la méthode render sur le renderer avec en paramètres : la scène et la caméra.

 

6) Animation : animate() / renderLoop()

3JS

function animate() {
 
    requestAnimationFrame( animate );
 
    // Animations here
 
    render();
 
}
 

BJS

function renderLoop() {
 
    engine.runRenderLoop(function () {
 
            // Animations here
 
            render();
        });
 
}

Ce sont des fonctions qui tournent en boucle.
Nous créons une nouvelle fonction render().

 

7) Rendus

3JS

function render() {
    renderer.render( scene, camera );
}

BJS

function render() {
    scene.render();
}

 

8) Redimensionnement automatique du canvas

Pour 3JS et BJS :

window.addEventListener( 'resize', onWindowResize, false );

 

3JS

camera.left = window.innerWidth / -2;

camera.right = window.innerWidth / 2;

camera.top = window.innerHeight / 2;

camera.bottom = window.innerHeight / -2;

 

camera.updateProjectionMatrix();

 

renderer.setSize( window.innerWidth, window.innerHeight );

BJS

engine.resize();

 
 
 
 
 
 

 

9) Plein écran

3JS nécessite une librairie externe (ce n’est pas le cas de Babylon.js) :

<script src="THREEx.FullScreen.js"></script>

 

Plein écran par raccourci clavier :

3JS

THREEx.FullScreen.bindKey({ charCode : 'p'.charCodeAt(0) });

 

 

 

 

 

 

 

 

BJS

BABYLON.Tools.RegisterTopRootEvents([{

    name: "keydown",

    handler: onKeyDown

}]);

 

function onKeyDown(evt) {

     if (evt.keyCode == 'p'.charCodeAt(0) || 'f'.charCodeAt(0)) {

        engine.switchFullscreen(true); 

    }

}

Avec 3JS, on ne peut seulement utiliser le plein écran avec les raccourcis clavier avec cette méthode.

Avec BJS, c’est la méthode globale d’utilisation des raccourcis claviers.

La différence entre 3JS et BJS pour le plein écran se situe au niveau de la notion de plein écran sur la FENETRE et plein écran sur le CANVAS.

Avec 3JS c’est un plein écran sur la FENETRE, c’est à dire que tous les éléments du DOM seront affichés.

Alors qu’avec BJS, le plein écran est géré par le moteur lui même, et seulement les élements du CANVAS seront affichés, le pointeur de souris peut également être masqué, etc...

 

Switcher de mode plein écran :

3JS

if( THREEx.FullScreen.activated() ){

    THREEx.FullScreen.cancel();

}else{

    THREEx.FullScreen.request();

}

BJS

engine.switchFullscreen(true); 

 

 

 

 

10) Affichage du nombre de FPS (Frames Per Second)

Pour 3JS et BJS :

.html

<script src="libs/stats.min.js"></script>

 

.js

stats = new Stats();

stats.domElement.style.position = 'absolute';

stats.domElement.style.top = '0px';

document.body.appendChild( stats.domElement );

Il faut ensuite ajouter le code suivant dans la fonction en boucle, animate() et renderLoop() respectivement pour 3JS et BJS :

stats.update();

 

11) Ajout du panneau de contrôle (BJS uniquement)

Le panneau de contrôle possède une couche de debug et un bouton Fullscreen dans cette version proposée.

La couche de debug permet d’afficher de nombreuses informations, tels que les noms d’objets, l’affichage en wireframe, le nombre de vertices,...

.css

Bas du formulaire

#controlPanel {

    bottom: 0;

    height: 100px;

    left: 50%;

    margin-left: -110px;

    position: absolute;

    transform: translateY(100px);

    transition: transform 0.25s ease-in-out 0s;

    width: 220px;

    z-index: 10;

}

 

#controlsZone {

    background-color: #dedede;

    border-top-left-radius: 10px;

    border-top-right-radius: 10px;

    color: #888888;

    height: 100%;

    padding: 10px;

    width: 100%;

}

 

button {

    background-color: #cecece;

    border: 1px solid #888888;

    color: #888888;

}

 

#enableDebug, #fullscreen {

    margin-left: 50px;

    width: 100px;

}

 

.tag {

    background-color: #dedede;

    border-top-left-radius: 10px;

    border-top-right-radius: 10px;

    color: #888888;

    font-size: 18px;

    height: 40px;

    left: 50%;

    margin-left: -75px;

    padding: 5px;

    position: absolute;

    text-align: center;

    top: -40px;

    width: 150px;

}

 

#clickableTag {

    background-color: transparent;

}

 

.js

Haut du formulaire

Bas du formulaire

Bas du formulaire

function addControlPanel_BJS() {

 

    // Show Control Panel

    var html = '<div id="controlPanel" class="" style="transform: translateY(0px);">' +

                    '<div id="controlsZone">' +

                        '<p> <button id="enableDebug">Debug layer</button> </p>' +

                        '<p> <button id="fullscreen">Fullscreen</button> </p>' +

                    '</div>' +

                    '<div class="tag">Control panel</div>' +

                    '<div id="clickableTag" class="tag"></div>' +

                '</div>';

 

    $('body').append(html);

 

    // Add Debug Layer Listener

    var enableDebug = document.getElementById("enableDebug");

    enableDebug.addEventListener("click", function () {

        if (scene) {

            if (scene.debugLayer.isVisible()) {

                scene.debugLayer.hide();

            } else {

                scene.debugLayer.show();

            }

        }

    });

 

    // Add FullScreen Listener

    var fullscreen = document.getElementById("fullscreen");

    fullscreen.addEventListener("click", function () {

        if (engine) {

            engine.switchFullscreen(true);

        }

    });

 

    // Hide Control Panel

    var panelIsClosed = true;

    controlPanel.style.webkitTransform = "translateY(100px)";

    controlPanel.style.transform = "translateY(100px)";

 

    // Add Control Panel Listener

    document.getElementById("clickableTag").addEventListener("click", function () {

        if (panelIsClosed) {

            panelIsClosed = false;

            controlPanel.style.webkitTransform = "translateY(0px)";

            controlPanel.style.transform = "translateY(0px)";

        } else {

            panelIsClosed = true;

            controlPanel.style.webkitTransform = "translateY(100px)";

            controlPanel.style.transform = "translateY(100px)";

        }

    });

 

}