So we will kick off the second installment of Let’s Make a 3D Game with HTML5. This series of tutorials is meant to help one get a better understanding on how to create a slick 3D game with the newest of WebGL technologies.
As stated before in my previous tutorial, we are going to be building a 3D shooter that is an homage to some of the classic games of yesteryears. The goal of this installment of the series is to get an understanding of how to create a graphics pipeline. But before we get to into the nitty-gritty, we need an update on some of the tools and frameworks we are going to use.
Selected Frameworks and Tools
This is in addition to the list from the last tutorial in the series.
- MAMP: Quick set up of a local server for web development on OSX.
- Sparks.js: Particle engine built on top of three.js.
- Ammo.js: Physics engine for collision detection.
- ThreeConvert: Utility for batch converting .obj files to .js format.
- ThreeFab: JSON .js asset viewer
- irc.freenode.net #three.js: chat room for three.js help
According to Wikipedia, “the graphics pipeline typically accepts some representation of three-dimensional primitives as an input and results in a 2D rasterized image as output.” In our case, the 3D models we are going to create for the project are going to be rasterized by our draw engine–which is WebGL. This is done with the help of the abstracted layer that is three.js. Boiled down, the graphics pipeline is detailing how we are going to get our art into our code.
Before we even get into exporting our models, we need to talk about 3D packages. The current application for creating 3D assets for this project is going to be Cinema 4D. There are much better alternative 3D packages for setting up a pipeline to three.js. Currently, Blender comes out on top as the best software for integrating models into three.js. This is mainly due to the add-ons that let you export and import the native JSON three.js format. The second in line is 3ds Max, a popular 3D package that is exclusive to Windows. It is also the application of choice for most of the AAA game industry at large. Max via a plugin lets you export to the native JSON format while importing is not supported as of yet.
The rest of us who are not on Windows and those of us who detest Blender (any real 3D artist) are left with the very few alternatives. The first method is to output as an .obj or .fbx file and then convert to the native JSON format by using the python scripts that comes with three.js. To compile problems, the script for converting .fbx files is extremely outdated, in turn leaving us with the only choice of our export format as .obj. It must also be stated .obj files have no support for bones or animations, but for the current project, static meshes will work fine. Also, for those of you who can’t be bothered with command line utilities, there is ThreeConvert–an OSX utility app that lets you batch convert .obj files. The second method is to export as a COLLADA file format.
Note: All the plugins and exporters can be found inside of the three.js package in the folder utils/exporters.
JSON vs XML Fight!
Although the COLLADA files seem to work fine, the optimal method for importing 3D objects into three.js is to use the native .js format. The reason for this is due to the speed of JSON vs XML on the web. COLLADA documents are descriptions of digital objects using an XML schema to exchange digital assets in various graphics applications.
With traditional game development, the issue of loading large files is trivial being that the files live on the hard drive. The low latency between the data storage of the hard drive and the CPU lets native applications deal with large formats with minimal effort. This is the opposite case with the Internet. Your browser is only fast as your Internet connection and the choice of file formats plays a crucial role in the speed of your application.
It has to be stated that the development of the COLLADA loader has currently ceased. There has been interest shown from The Khronos Group to pick up work for the loader, but at the current time, nothing has come of it.
Getting Baked with Tricks of the Trade
At the end of the day, all we want are clean assets in our game and we have to choose the best set of methods to accomplish this task. Being that we are dealing with the limited nature of webGL, we are going to have to employ a few tricks to get our assets to look nice and pretty inside of our game. The avenue we plan to take is a trick used in such games as Mirrors Edge and Proun. The style of our game is very simplistic but the visual fidelity of the objects can be improved upon by using Global Illumination(GI) and Ambient Occlusion(AO). These graphics rendering techniques are very processor intensive and virtually impossible to accomplish in a real time web based game. But, what we can do is bake the lights and AO into our game before exporting our models.
The game Proun used these techniques with some beautiful results, as you can see with the sample image below. If you have yet to play the game, go download it now! It is ok, this webpage will still be here when you get back.
The baking of GI and AO are a little bit out of the scope of this article. But, thanks to the awesome people of the Internet, detailed explanations have already been made on these subjects. Below is a list of the tutorials.
- Bake Object in Cinema 4d – YouTube
- Baking GI Basics – C4D Café
- Cinema 4d GI Baking with Importing into Unity Pro – YouTube
So what have we learned? Exporting from C4D into three.js is no easy task. But, the pipeline has been forged and it is too late to switch 3D packages. Down the line, I “might” consider using Blender, but a better option would be to create an exporter for C4D that creates JSON objects. Scale is another issue that was tackled while exporting. Generally the smaller the better; it is best to work at a millimeter scale when creating 3D models or just resize objects accordingly during exporting or loading. Another gotcha that one might run into deals with the local center axes of assets. If the object you are exporting is going to animate and move, it is important to set the local center point at the origin of the 3D package. With assets such as backgrounds or scenery, it can be advantageous to set its position inside of the 3D package as opposed to hand setting it in your coding environment.
At this point in the article, you must be asking yourselves where is the big payoff? So without further adieu here it is: Shooter01
Now, if you are not all that impressed, it is ok. Mind you, this is what is referred to as the Black Triangle. It is the journey that the object had to take to get on to the screen. It had to pass through a modeling tool, then to a converter program, then had to be loaded into the three.js code fully textured, and then finally rendered. The black triangle is a statement of a complex system being completed and now we can put work into doing more cool stuff.
When dealing with bleeding edge technologies, it is guaranteed you are going to run into unforeseen roadblocks a lot of the time. It is going to be up to you to forge ahead and set a path that has never been taken before. You will have to learn to roll with the punches. Just because there is a lack of documentation of what you want to accomplish, it should never hold you back. One great thing about three.js is the helpfulness of the community. With a little bit of digging around, you can easily find someone that will help answer your questions. Any framework is only as good as the people that are supporting it. So with that stated, if you have any questions please feel free to contact me or leave a comment.
Coming up, we plan to get the ship moving around and firing some bullets.
- Quick overview of three.js.
- Moving the ship via input commands from the user by JS event methods
- Shooting lasers and bullets