Performance doubts(commercial project)


First of all i want to say that i’m super impressive about babylon.js and its entire ecosystem. It’s amazing work, guys!

I’m writing this post to find answers and erase all my doubts if babylon.js is mature enough to be use in commercial project with good performance on desktop and mobile devices.
I’m pretty experienced developer but my area is 2D and i’ve used many of 2d engines, recently i’ve been working with pixi.js for last 5 years. However i’ve never wrote anything complex in 3D so i would appreciate your help but also please don’t hesitate to tell me i’m mistaken or sounds stupid cause my 3D experience equals zero :slight_smile:
Currently i’m gonna lead new projects - simple games but they will be mix of 2D and 3D. Some of them will consist of two separate scenes(one in 2D and 3D) and another ones will have two layer - one 2D and 3D and 3D could interact with 2D. I would like to use babylon.js as it seems to be perfect for this project but still have some doubts. My concers are mostly about good performance. I’ve beed reading all section in doc about optimalization but still have feeling like some simple(but yet powerful) techniques are missing

  1. Do you think it’s a good idea use babylon.js for such kind of project or maybe would be better to stick with some 2d engine and try to add 3d elements by my self?

  2. batching - i.e in pixi.js sprites using the images form the same texture atlas can be draw in one call (Inside PixiJS: Batch Rendering System - The Startup - Medium). This give us huge performance boost without loosing flexibility. Seems like this feature is missing in babylon.js, am i right?

  3. sprite sheets(aka texture atlas) - it’s a bit connected with previous one. Seems like right now there is no way to use spritesheets in babylon.js. I think wold be nice to be able to create shared material with base texture for couple of meshes and then use only part of it, but different part for different mesh. Do you think it makes seans?

  4. texture variants - it there any any way to use different texture variants, i.e on desktop i can have HD resolution but on mobile i load SD and engine scales it to proper size? Or do i need to handle it by my self?

  5. bitmapfonts or distant fonts - based on my knowledge it’s super simple way to achieve good performance for dynamic texts(my games will have plenty of them). Are there any plans to add support for it?

  6. limit FPS - is there a simple way to limi FPS? from my experience i’m know that having game in 30fps is enough and there is no need to target 60fps.


Hi @gao and welcome to the forum. Sorry that it taken a long time before getting a reply. Seems that a lot of questions have been asked and unfortunately yours seems to have been missed. I can try to answer some of the earlier question and perhaps @Deltakosh might be around to answer more precisely.

  1. I would go for babylon.js but then I am biased and starting from scratch with 3D is not easy.

  2. You can mix pixi.js with babylon.js How to combine Babylon.js and Pixi.js - Babylon.js Documentation

  3. If you and I mean the same thing by spritesheets then they are available:
    for sprites Sprites - Babylon.js Documentation
    for 3D Babylon.js Playground, more detail Apply Material to Individual Faces - Babylon.js Documentation. You need some understanding of uvs Apply Bumps, Opacity and Tiling - Babylon.js Documentation


Hello and welcome!! Adding some additional info:

Firs you may not know it but Babylon.js is used by very large projects like:

  • Microsoft PowerPoint for the Web
  • Microsoft SharePoint Spaces
  • Microsoft Teams
  • Microsoft OneDrive
  • Microsoft Bing
  • Adobe Dimension

and my more (you can find more demos here

To your questions:

  1. Definitely a good idea.
  2. We do support geometry instancing where meshes with the same material are rendered with one draw call. Where texture are the unit of work in 2d, in 3D the unit is the material and thus we instantiate at that level. Anyway, we also automatically reuse textures that are shared so they only exist once in memory: Use Instances - Babylon.js Documentation
  3. Already work. You can have two materials that point to the same texture with different uv offsets and uv scale. Texture.uOffset, Texture.vOffset can be used to read from specific pixels or you can also play with the uv vertex buffer of your meshes while sharing the same material
  4. The scale is automatic. But you will have to detect that you are on mobile to load a different texture
  5. For text rendering we rely on Babylon.js GUI (which uses Canvas2D) but I will be happy to chat more about bitmap fonts. So far I do not plan to add support for it but it is a community project so if someone is interested to work on it could be cool
  6. You can provide your own renderLoop and decide to skip one frame every two frame :slight_smile:

Hope this helps!


and last 2 cents coin :
you can mix the sprite sheet feature (here, by using the UV property) and the single draw feature to render any bunch of 3D objects that you want by using the Solid Particle System (aka SPS) whatever these objects are all the same or not, tiny or big, numerous or not


Hello, thanks guys for quick responses.


  1. I’m thinking about this as well but i’m see couple of disadvantages here, i.e 2 dependencies to be maintain, hard to interact between 2d and 3d, hiring new people with skils in both, etc :slight_smile: That’s why i would stick with one engine, but i’m not saying definitely no, probably will dig it a bit more(will prepare some PoC)

  2. yes, i believe we have the same in mind but my version is a bit more flexible :slight_smile: Spritesheets in babylon.js require that all images have the same size. In my version would be nice to load sprite sheets generated by i.e Texture Packer and be able to put in it different images with different sizes or even rotation.
    This Apply Material to Individual Faces - Babylon.js Documentation is super cool! I had to miss this once i was reading doc :slight_smile: faceUV is the key :). This will be helpful for me in 100%. Would be nice to read UVs from json instead of calculation it in code but i can write some level of abstraction which handles it for me.(but could be useful to baked it into engine as well?) Thanks!


  1. will look into instances with details soon, thanks!
  2. yeah, i thought that Texture.uOffset, Texture.vOffset could work, but thought that maybe there is a bit higher level mechanism to read this data from i.e generated json(but i can write it by my self - no problem)
  3. So i can load i.e my_textures@2.png and my my_textures@1.png? Haven’t seen this in doc? Or i just need to set scale for texture manually? Detecting desktop/mobile is not a problem.
    5.Having possibility to use Canvas2D and DynamicTexture is totally awesome!(btw, it is one of the reasons i consider babylon.js :P) For sure will use it in my project, but still think that bitmapfonts(distants font) could be helpful. I will have more insights here once i will be more familiar with babylon.js and start adding texts into project. Then i can even write it by my self and prepare merge request :stuck_out_tongue:
  4. yes, this is what i thought but wasn’t 100% sure. So instead of using engine.renderLoop(()=>scene.render()) i can use myLoop(()=>scene.render()) and this wont break anyhing?


SPS - i saw this, thought it’s only for particles but seems like it’s more flexible than i that :slight_smile: Thanks will check it as well.

To sum up, thanks guys for you input. It helps a lots. I will start some PoC soon to test everything in reality but now, i feel in my bones that babylon.js will be my engine of choice :slight_smile:

you can do a SPS with 1, 2, 6, 100, 10K “particles”.
A “particle” is just a 2D (planar) or 3D object whatever its size and its vertex number.

Nope :slight_smile: Each sprite can have its own size like:

player.width = 0.3;
player.height = 0.4;

I’m also really interested in the method to have the point 4 working (adapting the texture for a given platform)

Well this is just:

if (mobile) then texture = new texture(url1) else texture = new texture(url2)

Ho! I was expecting a more generic solution in the engine ^^’

sorry :slight_smile:

@Deltakosh i meant images in spritesheet, they need to have the same size right?

nope as each sprite can define its own width and height. Images inside the sheet must all be inside a defined rect but then each sprite can pick a portion of that rect

I did not know that and having read the docs do not yet know how a sprite picks a portion of the rectangle.

Have been playing with different size images on a spritesheet for faceUvs and front and back uvs. Will have to look more into spriteManager. However have been experimenting with using JSON

Here are the experiments

#2 is in billboardMode so a bit more sprite like.

Well this is the goal of .width and .height sprite properties

I think (and I may possibly be wrong) that what you mean for three sprites, green, orange and red they all have to belong to the same size blue rectangle. So that the file is like this


Whereas @gao wants the sprites packed like this


and you would need positional information as well as width and height information

I agree :slight_smile: this is not ideal but I wanted to offer an intermediate solution :slight_smile:

Yes, @JohnK. This is what it meant :slight_smile:

@Deltakosh do you think that we could add this higher level to the engine(reading UVs, size, position from json)? or it’s better to stick with middle-level API?

Is what I did with JSON in previous post using assetsManager in PGs Babylon.js Playground and #1 and #2 what you mean by middle-level API?

1 Like