Jump to content

How do I know if three.js will work for my game?


Recommended Posts

Hi, I'm new to this forum, but I hope you all can help me.  I want to make a 3D video game.  I want to do it in webGL so it will be easy to share with people.  When I message my friends and say "Look at this thing I made!"  It's easier to get them to click on a link than to download an executable.  That's why I've been reluctant to learn Unity or some other desktop game system, even though I understand they can get better performance.

What I'm trying to figure out is: Will webGL work for my idea?

I'm having doubts because I put together a little graphics experiment with three.js and I'm not getting good performance at all.  The scene I'm rendering is much smaller than I was imagining for my game and the framerate is already tanking.  It seems like I'm just drawing too many polygons.  I've got about 50K triangles in the scene to get it to look the way I want with all the curved corners and everything.  When I query the renderer object, it tells me that about 20K are being rendered at a time.  It seems like the automatic frustum culling is already buying me a lot.

I want to make big old space ships with long corridors and many rooms to explore.  I'm feeling that if half a dozen rooms is taxing the browser like this then I might not be able to do what I want.  I could redo this experiment in a few different frameworks and compare the performance and development experience, but I'd like if I could benefit from the expertise of all of you. ?

So, what do you think?  Is this going to be do-able?  Am I going to have an easier time with a different framework like babylon.js?  Do you think I am wasting my time with html5 and if I want to run around in a giant 3D space ship then I need a conventional game engine?

I don't know the rules for links on this forum, so I hope this is OK. Here's the demo I made that I'm talking about: http://safiina.com/dev/

Link to comment
Share on other sites

Hey @bluewales, welcome to the forums!

Demo looks great! Sounds like an awful lot of triangles for that small area, but, very nice looking and was a solid 60fps on my machine (which has a terrible GPU).

You've done absolutely the right thing, by reducing your use-case to a POC of the bit you want to test.

Yes, trying with some different library choices _can_ sometimes be a good plan, but, it can also be time consuming.

Three.js is incredibly well supported and used, try looking for demos or experiments that also are close to your requirements. If you find a couple of demos that are similar to what you want to do and work well, then you have to look at how you can optimise to achieve the same performance.

Think of it this way: if you have just picked up Three.js, it is a complex library, you can't expect to know exactly how to use it right off the bat. Now you want to test babylon.js, and you don't know that intimately either, so, POC's are tricky when testing performance, have a look also at some reduced use-cases. For any of these renderers there will be frustrum culling and raw number of triangles demos/tests that you can use to get a gauge on whether things are even possible.

An example of an optimisation: You may not need the curved corner geometry for anything other than pretty visuals, you can round/curve corners via a shader and have square corners, if you find that the number of triangles is prohibitive with curved corners then cheat.

The browser has one advantage over other platforms, debugging is incredibly easy with the browser and JS. Use the tools, find where any bottlenecks are, this will help you identify if there is an underlying issue or just a library/tech choice one. Bare in mind that the browser has the same access to the GPU as any other application (albeit with a slightly older language spec) so any bottleneck may very well be JS, which is _usually_ slower than other languages that you might use (outside of the browser, you have no choice in the browser).


Link to comment
Share on other sites

This does look good, and I completely agree with your assessment of the tech.

I didn't get 60fps I got more like 44, but I'm on a lower spec machine.

I think 'your problem' is that the patterns are solids, which makes the scene really complex, rather than a texture applied to the base plane. I'm not certain with Three about applying textures to your curved edges (I expect you can do it, I'm a little rusty with it.)

Link to comment
Share on other sites

@mattstyles Thanks for the feedback.  I think you hit on my main frustration in I can't adequately evaluate a technology without being an expert in it.  My naive POC doesn't do a good job of demonstrating the library's abilities.

Luckily, it looks like there are lots of tricks to learn.  Already I found out that three.js lets you merge geometries into a single, larger geometry.  Then that geometry only needs a single draw call.  By making some obvious merges, I was able to bring the draw calls down from ~2500 to about ~800.  That made a noticeable improvement on my frame rate.  I think I was wrong in saying the number of triangles was driving my performance, it looks like the number of draw calls was making a bigger impact.  With more aggressive merges I should be able to get the draw calls much lower.

It also occurs to me that if the camera is in a room with a closed door then I can remove the rest of the ship from the scene entirely.

I'm a little overwhelmed with the amount of work it's going to be,  but I'm even more relieved that it looks like it's going to be possible.

Thanks for the encouragement.

Link to comment
Share on other sites

8 hours ago, charlie_says said:

I think 'your problem' is that the patterns are solids, which makes the scene really complex, rather than a texture applied to the base plane. I'm not certain with Three about applying textures to your curved edges (I expect you can do it, I'm a little rusty with it.) 


I think I see what you mean.  The green trim could be a texture.

Link to comment
Share on other sites

Hey there. Both Three.js and Babylon.js are suitable for the job. If optimized, rendering 50k triangles in WebGL is not an problem for desktop computer.

As you have found out, problem is draw calls. It's not WebGL, Three or Babylon related, it is same across all rendering engines. Everytime rendering engine needs to change shader, it generates new draw call (there are few more cases when new draw call is generated)

Order of rendered elements is crucial.

Let's say in your scene you have: wall, decoration, window, wall, decoration, wall; all types using different material (shader). If you draw them on screen in such order, material has changed 6 times -> hence 6 draw calls. 
But if you draw them in wall, wall, wall, decoration, decoration, window order -> you get 3 draw calls. You have successfully reduced draw calls by merging same type of geometries inside of one cube. But you have X cubes in your scene.

So, next thought would be to merge all walls in scene into single mesh, all decorations in scene into another mesh, etc. In ideal world you will end up with one big mesh for walls, one big mesh for decorations, ...
Avoid doing that for very large scene as you will loose culling capability. Divide it in reasonable large groups - you have to play with it and tune it up directly for your scene.
As mentioned, you can reduce geometry/materials by using single texture applied to wall. If all your walls don't look same, merge couple of wall textures into one texture atlas and use 3D modelling app (Max, Maya, Blender) to shift UVs around it.
You can still use normal map on top of it to make your decorations look like they are offsetted from wall. And you can also experiment with using LODs, instances.

Hope that helped a bit, one last advice: fake everything you can :)

Link to comment
Share on other sites

  • 2 weeks later...
On 7/2/2019 at 3:30 AM, bluewales said:

When I message my friends and say "Look at this thing I made!"  It's easier to get them to click on a link than to download an executable.

I like it very much too. You can make not only games but something useful. I made this simple example using Three.js: http://8observer8.freevar.com/threejs/flat-plan/ I think it can be useful to make 3D plan of flats.

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.

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.


  • Recently Browsing   0 members

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