Quaintproject

Exporting from Blender to Web GL using Collada and three.js (part 2)

19 Comments


webgl

Exporting from blender to web.gl using three.js

In this series I’ll show you how we create your own basic webGL viewer.

In the first part we talked about the necessary software and scripts.

Setting up a basic scene for three.js

I’ll start with my code for the webGL right between the two script brackets. We could have created an external script but I think keeping the html and javascript together makes it easier to understand what we are doing.

Create the Scene

In order to render a scene in three.js we need a scene itself, a camera and a renderer

var scene, camera, renderer;
    init();
    animate();
    function init() {

      scene = new THREE.Scene();
      var WIDTH = window.innerWidth,
          HEIGHT = window.innerHeight;

      renderer = new THREE.WebGLRenderer({antialias:true});
      renderer.setSize(WIDTH, HEIGHT);
      document.body.appendChild(renderer.domElement);  
      camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 10000);
      camera.position.set(50,150,100);
      scene.add(camera);
      window.addEventListener('resize', function() {
        var WIDTH = window.innerWidth,
            HEIGHT = window.innerHeight;
        renderer.setSize(WIDTH, HEIGHT);
        camera.aspect = WIDTH / HEIGHT;
        camera.updateProjectionMatrix();
      });

Let’s first create a scene…

      scene = new THREE.Scene();
      var WIDTH = window.innerWidth,
          HEIGHT = window.innerHeight;

Next let’s create the renderer…

      renderer = new THREE.WebGLRenderer({antialias:true});
      renderer.setSize(WIDTH, HEIGHT);
      document.body.appendChild(renderer.domElement);

three.js also offers you other render engines than the webGL Renderer which could be used as fallbacks for browsers that can’t handle WebGL. But please note that WebGL will be one of the fastest methods as it makes use of your graphics card. 🙂

To get the max. resolution I set the size to be window.innerWidth respectively window.innerHeight. You could also crop calculation times by lowering the resolution e. g. window.innerHeight/2.  Your final result might look a bit blurry and scaled up. Finally we add the renderer element to our html document.

I set the antialias to true. The default is false. By enabling antialias we should get a bit smoother edges.

In the next step we’ll go ahead and create a camera.

Camera and action..!

Creating a camera is really important otherwise we wouldn’t be able to see anything. Three js offers you to create a perspective Camera or a an orthographic camera, which could be interesting especially for 2 d animations. In our case we will be using a perspective Camera.

There are some settings we might want to tweak.   The first setting is the  field of view. I set the value to about 45 degrees (~50 mm). As it’s quite natural to look at for the human eye. Next we have to set the aspect ratio to Width/Height. Very often you want to set this aspect ratio otherwise it might look squished. The near is set to a very small number and the camera frustum far is set to a quite high number. Next we set the position and add it to our scene. If you want to learn more about the camera in three.js click here. Place this code inside function init.

       camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 10000);
      camera.position.set(50,150,100);
      scene.add(camera);

Update the Viewport on Resize

Let’s add a code snippet inside function init () so that whenever the user resizes his browser window the projection matrix will be updated.

window.addEventListener('resize', function() {
        var WIDTH = window.innerWidth,
            HEIGHT = window.innerHeight;
        renderer.setSize(WIDTH, HEIGHT);
        camera.aspect = WIDTH / HEIGHT;
        camera.updateProjectionMatrix();
      });

//more code to come...
}

Adding the OrbitControls functionality

First we have to import the Orbit controls script though. In current three.js version you find this script here: three.js-master\three.js-master\examples\js\controls\OrbitControls.js

Place the following code right after importing the three.min.js file.

<script src=”js/OrbitControls.js”></script>

Add the following line of code in order to do rotate, grab or zoom inside the view port. Place this code inside function init() in order to allow interactions.

controls = new THREE.OrbitControls(camera, renderer.domElement);

Adding in function animate()

In order to redraw the scene when rotating the camera we need to add the following command. Place it after adding our controls and outside function init ()

  function animate() {
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
      controls.update();
    }

Blinded by the light…

Now it’s time to add lights to our scene. I actually go for some proper three-point lighting. Including a key light, a backlight and a rim light to make positioning easier I add little spheres that indicate where lights are in 3d space. Their opacity changes depending on the strength of the light. make sure to apply different colours, to have some variation in your lighting. Add this code after the event listener and inside function init (). The value after the colour defines the strength of our point lights.

      var light = new THREE.PointLight(0xfffff3, 0.8);
      light.position.set(-100,200,100);
      scene.add(light);

var sphereSize = 1; 
var pointLightHelper = new THREE.PointLightHelper( light, sphereSize ); 
scene.add( pointLightHelper );

      var light2 = new THREE.PointLight(0xd7f0ff, 0.2);
      light2.position.set(200,200,100);
      scene.add(light2);

var sphereSize = 1; 
var pointLightHelper2 = new THREE.PointLightHelper( light2, sphereSize ); 
scene.add( pointLightHelper2 );

var light3 = new THREE.PointLight(0xFFFFFF, 0.5);
      light3.position.set(150,200,-100);
      scene.add(light3);

var sphereSize = 1; 
var pointLightHelper3 = new THREE.PointLightHelper( light3, sphereSize ); 
scene.add( pointLightHelper3 );

Interim result of a basic scene created in three.js

So all we get is a white screen. That’s because if  you don’t apply any specific background colour the background will be  displayed with a white colour. Later down the road we will add in a sky dome with a gradient to make everything more appealing.  Of course there is no 3d model to be displayed either, so let’s add in one! 🙂

interim result webGL


Exporting a 3D Collada 3d model from Blender

First we need a  3d model we want to view. If you have none to hand you can go ahead and download our ball in maze 3d model. Just change to the download tab. If you are using your own 3d models to make sure you use a model that is prepared for Blender Internal instead of Cycles. This will make exporting much easier. Go ahead and select the models of your scene you want to export. Make sure that you’ve always selected the surface texture instead of the bump or spec map. make sure that under “mapping” your UV-Channel is set, unless you are using only one UV-Map or you are using other mapping methods. Please note there are quite a few ways to map textures to objects. If you don’t know how to do so, just watch one of the many tutorials out there e. g. Blender Cookie 🙂

ball in maze

Select the frame and the obstacle mesh by pressing shift+ right click, then go to file export, Collada. The Collada exporter should be enabled in all latest, official blender versions.

Collada is a file format that is developed by the Khronos Group, just like WebGL. The Khronos Group a industry consortium that was founded in 2000, aimed to set up and maintain open standards in the field of multimedia. Some famous members are NVIDIA, Google, Apple, Unity 3D, mozilla and many more.

As far as I know the blender institute has hired a paid developer in the past to implement the Collada exporter. This might be a reason why this exporter has so many options… 🙂

Please note we are using a Collada In- and Exporter. You could also try the three.js addon for blender. The necessary exporter is included in the three.js utility folder.
If you plan to use the three.js exporter for blender you’ll need a jason importer in your javascript instead of the Collada importer. Learn  how to export from Blender to three.js here.

export collada

Save your model into the models folders. You might want to call it dummy1 as well. This will make things easier later down the road. Of course you can give it a different name, you just have to remember to change the name in the script as well, in order to display the mesh.

Choose Apply modifiers and selection only. Under texture options choose Only Active UV-Layer, include UV-Textures and copy. Save the .dae file.

export2

Now let’s do a bit more coding…

Let’s import the ColladaLoader script, that we’ve placed in the js folder earlier. Place the following command right after the orbit controls script.

<script src="js/ColladaLoader.js"></script>

Add the following code to load your Collada model including textures. You can insert the code right after lamps. I think it’s quite self-explanatory…

var loader = new THREE.ColladaLoader();

  loader.options.convertUpAxis = true;

  loader.load( 'models/dummy1.dae', function ( collada ) {
 //dummy1.dae

    var dae = collada.scene;

    var skin = collada.skins[ 0 ];

dae.position.set(0,0,0);//x,z,y- if you think in blender dimensions ;)
dae.scale.set(1.5,1.5,1.5);

scene.add(dae);

});

et viola!

Refresh your browser tab and that’s what you should come up with….

interim2

So far you should have the following code:

Troubleshooting with three.js

Though it sometimes happens that nothing changes.  You could solve the problem by clearing the browser history including  Cache and Cookies.

cookie

Adding a grid and axis helpers in three.js

Add the code for the grid and the axis helpers right after the code for the Collada importer. The axis helper will help us to orient ourselves in the 3d space. We basically just create a new variable and set the length to 50. The axis position is set to be the position of our imported 3d model. You could also use an arrow helper instead.  Next we add a horizontal grid to our scene. You could also add vertical grids but this might be a bit over the top. Next just create one more variable. The grid size is set to 100 and the steps to 10. The position is set to be the centre of our world. We could have dropped this line of code, because by default your grid is placed at (0/0/0) unless you don’t apply any different position. 🙂

There are two colours we set. The first one is for the grid lines that cross point zero. I decided to give them the same greyish colour. See the result below to see what I came up with!

var axes = new THREE.AxisHelper(50);
	axes.position = dae.position;
	scene.add(axes);

	var gridXZ = new THREE.GridHelper(100, 10);
	gridXZ.setColors( new THREE.Color(0xFFC0CB), new THREE.Color(0x8f8f8f) );
	gridXZ.position.set(0,0,0 );
	scene.add(gridXZ);

grid and axis helper three.js

That’s it for part 2.

  • Go back to part 1
  • Continue to part 3 to learn about how to create a sky dome with a gradient under three.js and how to publish your files on a webserver.

Please leave a comment, if you come up with any questions. 🙂

Advertisements

19 thoughts on “Exporting from Blender to Web GL using Collada and three.js (part 2)

  1. Pingback: Exporting from Blender to Web GL using Collada and three.js (part 3) | quaint

  2. I copied all your code and what i got is a black page, what might be the problem? I am using google chrome to view the code.

    Like

    • Thank you, at the moment I am reviewing the code. I’ll try to send you feedback ASAP. Thank’s for your patience. Cheers Markus

      Like

    • Hi there,

      I am back with the solution. Obviously some scripting error was causing the black screen. I’ve already updated the final script. I am going to review the script in part 2 next. In the meantime you can also download my full project here: https://copy.com/NsU0qk7saJMDlnwN
      It worked now. (See screenshot)
      screenshot webgl

      Please tell us, if you still run into errors. (It’s always best if you send us a screenshot of your browser console plus code) 😀
      Thanks for your patience. Cheers Markus

      Like

  3. Thank you so much for your reply! I downloaded the whole project and tried to run it and the result is that I still get a black screen. After i change the the loader.load directory from to (which i put the dummy1.dae in the local server), there is a huge sphere in the screen when i zoomed out. Only three little white spots inside the sphere, when i changed the camera positions and i see those white spots are actually some boxs. There isnt any boxed that you showed above. Sorry i dont know how to upload an image in order to show you what i have got. What i want to achieve is just to load a custom 3d model which is in any type including .dae into a web window and it is able to rotate.

    Like

  4. After i change the the loader.load directory from
    loader.load( ‘models/dummy1.dae’, function ( collada )
    to
    loader.load( ‘http://localhost/dummy1.dae’, function ( collada )
    (which i put the dummy1.dae in the local server), there is a huge sphere in the screen when i zoomed out.

    here is the change I made, I dont know why the code part was missing in last comment.

    Like

    • Hi there, you were able to see this very big sphere, which works as a sky dome. I just forgot to limit zoom in the orbit controls script. As for the 3d model: place the index.HTML in your http docs folder, make sure you keep the folder structure. There must be a sub folder called scripts and one called models. Place the .dae model in the models folder. Please do not change the filepath for now. 🙂 The model linking you wanted to try in your last two comments,won’t work, if I recall this correctly. Hope this helps. 🙂 Cheers Markus

      Like

  5. Actually the boxes I talked about are quadrahedrons, thanks

    Like

  6. I tried once more and find these errors
    THREE.WebGLRenderer 69

    ColladaLoader.js:113 XMLHttpRequest cannot load file:///E:/WEBGL/models/dummy1.dae. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource.ColladaLoader.js:113 load

    ColladaLoader.js:88 ColladaLoader: Empty or non-existing file (models/dummy1.dae)

    ColladaLoader.js:113 Uncaught NetworkError: Failed to execute ‘send’ on ‘XMLHttpRequest’: Failed to load ‘file:///E:/WEBGL/models/dummy1.dae’.

    Thanks

    Like

    • Hi there, you were able to see this very big sphere, which works as a sky dome. I just forgot to limit zoom in the orbit controls script. As for the 3d model: place the index.HTML in your http docs folder, make sure you keep the folder structure. There must be a sub folder called scripts and one called models. Place the .dae model in the models folder. Please do not change the filepath for now. 🙂 The model linking you wanted to try in your last two comments,won’t work, if I recall this correctly. Hope this helps. 🙂 Cheers Markus

      Like

  7. Hey! thanks for this tut. it was so easy to follow. My code worked perfectly on the first try.

    Like

  8. Hi there.

    Is there specific reason you didn’t use var to declare the “controls” variable on line 79? I’m kind of confused about that.

    Like

  9. Hi there, there is now specific reason why the var is missing. It’s actually a bug. Please add it to your script and you should be good to go. 😀 Thanks for your comment. Cheers Markus

    Like

  10. The file .dae there are settings for camera and light.

    dae.scene.traverse (function (child) {
        if (child.type === ‘PerspectiveCamera’) camera = child;
    }

    But it did not work. I searched several examples and all create a new instance. Do you know why it does not work?

    Like

  11. Dear Team of quaintproject,
    I try this tuto….but I just see three white points on my screen…They move with the mousewheel…
    I get this error warning in my console : ColladaLoader.js:144 Uncaught TypeError: Cannot read property ‘nodes’ of null
    I am not sure about my “dummy1.dae” file…
    Is it to get one exact link for this file
    thank you very much

    Like

    • Hi there, the three points you can see on the screen are the indicators for the pointlights. If you don’t want to see the dots, just disable them in the script. All you need is a .dae / a Collada file, that is a also called dummy1.dae and saved at the same location. You can basically use any Collada file, you don’t have to use our file, of course you can. You will find the .blend file here: https://quaintproject.wordpress.com/download/. You’ll have to convert it yourself. Of course you can use different names for your callada object, but you will have to change the script then. Cheers Markus

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s