WebGL 3D model viewer using three.js

I made a low-poly model for our game, finished it around midnight and was looking for feedback from my friends. Taking pictures from every possible angle or even recording a short turntable animation were too much work for me as I had already been very tired. So I created a WebGL model viewer in three.js. This took me about an hour and propably much longer than the images would have but was so much more fun and exciting. Also my tiredness suddenly disappeared while working on the model viewer.

WebGL 3D model viewer using three.js

It turned out pretty well and that is why I want to share this small tutorial on how to build a WebGL 3Dmodel viewer with three.js. Before you start, you have to gather some things which you’ll be working with:

  • Your model in OBJ format. If you do not know how to export your model, please take a look at the manual of Blender, Maya, Modo or whatever software you are using.
  • You texture in PNG or JPG format, of course as a square power-of-two texture.
  • The latest build of the three.js library, mine is r61.
  • TrackballControls.js for cool camera control.
  • OBJLoader.js for loading the model and Detector.js, which detects if your browser can handle WebGL.

Put the files in a folder and reference them in a simple HTML page as in the code snippet below. I also recommend you to set some styles for the background, so your character does not have to sit in an empty white void. I like empty dark voids, so I set the background to black.

The code is pretty self-explanatory, so instead of explaining the different parts I have created comments. It may be easier to read if you paste it into an editor with syntax highlighting.

Et voilà! Your in-browser model viewer is done and you can show off your great models to your friends. I recommend the Getting Started with Three.js article and the three.js documentation if you want to dive deeper into WebGL.

Kind regards,

Art, Tutorials , ,
  • nick

    Thanks for the tutorial i like it but this is not working with the last Three.js.

    Is it possible to get an ubdate?

    • manuelwieser

      Hi Nick, I will have a look at it really soon and update the tutorial for r61!

    • manuelwieser

      I have updated the tutorial to work with revision 61.

      You have to
      1. get the newest scripts from GitHub (the links have been updated) and
      2. change the texture loading and obj loading parts as I did.

      Event management has been changed in the last few revisions, this is why the code was broken.
      Have fun and let me see what you do with it ;)

  • Abdul Haseeb

    I wanted to load a model but my model has multiple texture files, how to manage them, as you have only loaded one texture file into this tutorial

    • manuelwieser

      The easiest solution would be to just import your model as multiple parts and assign the correct texture to each. If you really need to have more than one texture on an object maybe this thread can help you:

      • Jayashree

        Hi , I want to use websocket for all events. Please share any link which is useful for websocket and webgl

    • oseroke

      Abdul, was the stackoverflow solution helpful? I don’t think it was for me. I’m having exactly the same issue you posted. Have you found a solution?

      • Abdul Haseeb

        Well, oseroke, I went to Unity frame work , and my problem was solved

  • thismarty

    Any chance you could post a ZIP archive of this awesome-looking bit of awesomeness? I’ve typed it in over and over, retrieved the required libraries, gathered up an OBJ/PNG, sprinkled it all with love and yet still can’t get it to work. I strongly suspect the issue is related to my severe lack of intelligence. But I’m sure a complete project set, wrapped up in a ZIP would show me the way. :-)

    • manuelwieser

      Of course, you can download the full example with all required files:

      • thismarty

        You sir, are my hero.

      • thismarty

        Well, durnit. I’m getting an empty browser on Safari 7 (with WebGL enabled) and Chrome and Opera, all under MacOSX 10.9 GM. Interestingly, it does work just fine on Firefox. Oh, WebGL – when will you ever work everywhere?

        • manuelwieser

          This has to do with the same-origin policy. In most browsers you are not allowed to open files from the local file system. Try and upload it onto your server and it should work in all browsers that support WebGL :)

          There is also a wiki entry from three.js about this issue.

          • thismarty

            Yeah, I caught that in the Error console and figured it out. That could make debugging without an internet connection a pain. ;-) Anyway, awesome demo! Any chance you could derive it to do FBX loading?

          • manuelwieser

            I have found a python script on GitHub (https://github.com/mrdoob/three.js/tree/master/utils/converters/fbx) that converts FBX files, but I have never used it.
            Here is a list of all loaders that @mrdoob created, OBJ still seems to be the most universally used format:

          • thismarty

            Thanks again. I’ve been wondering which format was preferred. FBX seems nice since it’s just one file, but I’m thinking now that having textures and meshes separate (a’la OBJ) might be better – for swapping, etc.

          • Ami

            That works if you uploded the files on a Server, Thanks!

  • Guest

    Hi, Manuel. I left a comment yesterday but it looks like I may have messed up – it’s gone. Anyway, your demo is awesome but I can’t get it to work. Any chance you could post a ZIP of the index.htm and supporting files that works? TIA!

  • Kouis

    Hi, thank you for sharing this tutorial. It helps me a lot in rending my 3D object. I wonder could you please give me some hints about writing a auto-rotation function which can create a turntable animation for the 3D model on the z-axle (you also mentioned in the animate() function)? I tried to call object.rotation.set() in the animate() function but the 3D model is gone in that case :(. I will really appreciate if you can share your idea on that. Thank you very much!

    • manuelwieser

      I guess you want to rotate the object around its own axis?
      This is a bit more complicated than rotating it around the world axis (which is what you get when setting object.rotation.y += 2.5;), have a look at this: https://github.com/mrdoob/three.js/issues/910
      Hope there is something that can help you in that issue thread!

    • trebbrennan

      Try this:
      Declare ‘object’ as a global variable (outside of any functions). Up where the variables; camera, scene, renderer, are declared works well. This way any function can use it.

      Find where object was previously declared:
      var object = event.content;
      Change it to an assignment not a declaration:
      object = event.content;

      Now you can fiddle with it in the animate() or render() function however you want, try something like this:

      var time = Date.now() * 0.0004;
      object.rotation.x = time;
      object.rotation.y = time * 0.7;

  • Jay

    Great script! I was curious if you could suggest how to modify it for an STL file. I downloaded STLLoader.js and plugged it into my script calls, but it does not read the STL file. I also changed var loader = new THREE.OBJLoader( manager ); to var loader = new THREE.STLLoader( manager ); I’m sure there is much more I should change. Any suggestions would be helpful. Also i want to be able to pass javasript variables to the webpage to adjust the rotation, zoom and position. Can you tell me how I’d do that? Thank you!

  • Brian de Jong

    Would it be a possibility to make this wonderful tool work with Sketchup models?

    • http://www.manuelwieser.com/ manuelwieser

      I don’t really know about SketchUp’s exporting capabilities. It just has to be able to export an .obj file. Try to look for that.

    • iggyglass

      Sketchup is able to export .obj files. To do this just click on file>export and select the .obj format.

  • Kevin

    Thank you, this was really useful for me as a starting point. I’m having trouble rotating the object though, not a great start :S As soon as I add “object.rotation.y += 0.01;” anywhere in the animate function, the model disappears. Do you know why that might be? thanks.

    • http://www.manuelwieser.com/ manuelwieser

      Are there any error messages in your console?

  • raj

    When I host the files you have given as zip… i get scroll bars in right and bottom and not full screen pls help

  • ManBoy

    Is there a way to incorporate momentum into this? If mouse is still moving when I let go of the button I want the model to keep moving via momentum

  • spogna

    i’m using this code for my 3d door scan but when rotate the object i view only one side.
    is it possible to view doubleside?

  • hesapadim

    So thanks! You saved my day! :)

  • Mubasher Khan

    Dear i,m getting the error in console THREE is not defined

  • dileep maurya

    hi can i make all the variables which are given hard coded value to dynamic values depending on .obj file because i have multiple models and are run through a link and are of different dimensions.so some models come bigger and some smaller some come upward and some downward.