Recently, I presented a Webinar for Pluralsight on
WebGL and three.js. Below is a list of questions from the audience, along with my responses. Please note that I have modified some of the text for clarity.
1. What framework or libraries do you suggest for supporting older Web browsers that do not support WebGL?
Your best option, if you are using the three.js library, is to try and fall back to the canvas-based rendering option. Canvas is supported in IE 9 and above. You can do this by checking for the existence of the WebGLRenderingContext on the window object:
var renderer = window.WebGLRenderingContext ? new THREE.WebGLRenderer() : new THREE.CanvasRenderer();
The Canvas option won’t support the full range of graphical effects possible with WebGL and probably will not be as performant. Remember, also, that as the three.js framework abstracts the renderer from the rest of the framework, you could even implement your own rendering option to render content using cat gifs or something! Additionally, there are a number of polyfill options, some based on Java, some Canvas, listed
here.
2. What's the best way to use real world (page) coordinates in your applications?
When you convert from screen/mouse coordinates to three.js world coordinates you need to perform a bit of math. Unfortunately, this is not straight forward! At a high level, you take the mouse click event coordinates and then project a line from them into the screen (as our 3D scenes have depth) and determine what you have hit, to work out the scenes x,y and z coordinates. I have an example of how to do this
here.
3. How does the object hierarchy work within the scene? Is there something like a DOM structure, so different objects can belong to the same container?
In the three.js world you add objects such as lights, shapes and models to a scene, which I guess you can think of as being a bit like document, as it is the top level container for most objects. Most three.js objects are hierarchical, so you can have parent/child collections of objects and transverse these. The hierarchy of an object has implications when you perform transformations such as moving an object and scaling and rotating it. I cover this in my Pluralsight course if you need more information.
4. How does Physijs apply physics to three.js scenes, and work out, if any collisions occurred?
At a high level, you must first tell Physijs a bit about your scene and the objects within it. When you first set up your scene, you define the scenes gravity, which will tell Physijs how objects should behave when they fall:
scene.setGravity(new THREE.Vector3( 0, -30, 0 ));
When an object is added to the scene, you can then set properties such as friction, restitution (this means bounciness!) and mass -- the Physijs engine then utilizes this to define how an object will behave when it interacts with other objects. For example, an object with a high mass will not be moved by an object with a very low mass unless it collides with it at a sufficient speed. Below is an example from Physijs site where we create a material with a high friction and low restitution. You would then apply this material to an object:
var friction = .8; // high friction
var restitution = .3; // low restitution
var material = Physijs.createMaterial(
new THREE.MeshBasicMaterial({ color: 0x888888 }),
friction,
restitution
);
The next step is to tell Physijs to calculate how our objects should behave. We do this with the simulate method on the scene object as part of the rendering loop. Note that Physijs performs these calculations in a Web worker, which runs in a different thread to avoid slowing down the UI.
scene.simulate();
To handle collisions we add a callback function to the collision event of the object we are interested in:
obstacle.addEventListener( 'collision', function( otherObject, relativeVelocity, relativeRotation, contactNormal ) {
if(other_object.name==='player'){
//handlePlayerDeath();
}
});
The callback function accepts a number off parameters, such as the other object that has collided with the main object, velocity, etc. that you can use to fine tune behaviour.
5. You started out with early versions of .NET but moved on to HTML5 and WebGL. Is there any point to learning anything else when HTML5 and WebGL can do almost anything?
It depends on what you want to do. For example, it is true that you can accomplish a lot with HTML5 and WebGL, but there are still some tasks where these technologies will not work so well, or at all. This can happen where performance is a priority or with embedded systems. In my full-time job, currently, I develop applications in .Net (MVC & WebAPI) which are appropriate technologies for our applications. For game development, I think HTML5 and WebGL are becoming pretty compelling choices due to their cross platform support. It is worth noting that the game development framework Unity has said it will support exporting to WebGL.
6. Can I use a Box3D library?
Three.js contains Box3 functionality – please see http://threejs.org/docs/#Reference/Math/Box3. I have an example of how to do this in
my course. I haven’t used any external Box3D libraries, but it probably wouldn’t be too tricky to integrate them.
7. I encountered the following error executing gameFinal example on my Mac, using the latest Chrome browser:
Uncaught SecurityError: Failed to construct Worker : Script file:///Users/username/Desktop/Development/WebGL_Webinar/gameFinal/js/physijs_worker.jscannot be accessed from origin 'null'physi.js:393
You will need to serve the example from a webserver as e.g. IIS on Windows platform and something like Express on a Mac. The main three.js site has information about how to
run applications locally. You should also check that the paths to the Physijs script and workers are correct for your setup, as these are defined as relative paths in app.js:
Physijs.scripts.worker = './js/physijs_worker.js';
Physijs.scripts.ammo = 'ammo.js';
8. How do you define the term “modern browsers?”
I count modern browsers as IE10+ and the last two versions of Chrome and FireFox, etc., but this is a bit of a subjective term. You can check current browser support for WebGL
here.
9. In the Webinar example, when you defined the scenes gravity, you used -30 as the Y parameter. What units are these specified in?
I am not sure, I think it’s an arbitrary value. The value defaults x and z to 0 and y to negative 10. You would probably want to experiment with these values to get the effect you wanted in your application.
10. What are some of the limitations/differences of the physi.js scene over the Three.js version?
Physijs scene is a wrapper for the standard three.js scene and adds some additional physics specific functionality. You would only use it if you were using the Physijs functionality.
You can check out what exactly the Physijs scene code is doing
here.
11. Does physijs has support for humanoid models?
Physijs does not, but you could put some of these shapes together to create a simple version of this. You can check out the shapes Physijs supports
here, and you could also look at constraints (e.g. a hinge)
here.