Previously, I went over the process of writing an Away3D parser but skipped how to actually interpret the data in a file. In this post, I’m going to talk about the structure of an OBJ file (less complicated than SOUR), how it’s typical of all 3D files, and how in Away3D or any 3D engine one would turn its data into a usable 3D object.

First, let’s actually look at a 3D file, a simple cube saved by Blender. This cube has sides 2 Blender units long and is centered perfectly. (Hence all the 1’s and -1’s.) It has a material file and is UV-mapped. Unlike SOUR, it uses quads (four-pointed faces like rectangles, diamonds, or squares).

Alright, let’s go through it.

#
The lines that begin with a pound sign (#) are comments. They can be deleted and it will have no effect on the file.

mtllib
The lines that begin with “mtllib” refer to the MTL material files exported alongside the OBJ file. In my experience, MTL files are fairly useless, so I’m not going to cover how they work here except to say that they do not contain the PNG or JPG file used for the texture, and that you can delete that line with little effect. Same for “useMtl” lines.

v
The lines that begin with “v” are vertices. You can see that each has an X, Y, and Z value. Furthermore, they are “indexed”. More on that later.

dao_mesh

vt
The lines that begin with “vt” are texture vertices. They’re in 2D space, so they only have X and Y coordinates. They will for the rest of this post be called “UVs”, since that’s more common.

dao_UV

useMtl, s
Next are a few more useless lines. The line with “useMtl” was discussed above. The one with “s” has to do with smoothing groups, which applies to 3DS Max only.

f
Next up are the lines starting with “f”. F is for face. This is where it gets interesting. Remember how I said the vertices were indexed? Each face has two numbers. One refers to a vertex, a “v”, and the second refers to a UV, a “vt” from the above lists of vertices and UVs. You’ll see that there are eight vertices and each of the face number-sets’ first numbers is in the range 1-8. See where this is going? The first face is a quad with the vertices 1,2,3, and 4, or:

By plotting those four points in 3D space, we reconstruct the first of the six quad faces of a cube. “Indexing” means listing each of the eight vertices only once and then referring to that vertex by its “index” number in the face information. This saves space and bandwidth. The alternative would be listing the actual “v” vertex information per face. The UVs are also indexed.

So, in a custom parser, if you were parsing line by line like the OBJ and SOUR parsers do, you’d read a line, separate the bits by the spaces in the line via something like AS3’s String.split() function, throw out the first one, and use the rest to form a vertex or UV. Once you had a list of vertices, UVs, and whatever other data was relevant, you’d use your 3D engine’s methods/functions to construct the Mesh object and put it onscreen. In Away3D, that looks like:

And that’s really it. Parsing is just taking data in one form, and making it readable to whatever needs to use it.

MakeHuman is a great tool for generating humanoid character models quickly. Still, it has its limitations. At present, the hair and clothing options are extremely limited, it can’t do non-humanoid avatars, and even its “proxies” are too high-poly for mobile games. Before I discovered MakeHuman, I learned how to create character models from scratch in Blender. It’s a skill which allows me to make up for MakeHuman’s shortcomings. In this post, I’ll give a brief overview of the process of manually creating a character model and provide links to Blender tutorials on the various steps.

Concept Art

To start, you’re going to need some concept art of the character you’re going to model. Concept art is more than just a few quick sketches when it comes to 3D modeling. You’re going to need side by side pictures of the character at different angles: at the minimum, a front shot and a side shot. The shots will need eyes, noses, clothes, etc. all to be lined up near-perfectly for the next step.

femaleFullColor

Creating a Base Model

Once you have your concept art, you’ll need to import it into your 3D modeling program and “trace” a low-detail version of it. This is not the final version, so don’t fret if it’s not perfect. Tutorial for Blender

Sculpting

In the sculpting step, you create a very high-detail version of your character model. This is also not the final model, but pretend it is. (This high-detail model will be far too high-poly for most game engines to handle.) You’ll be using this to create a normal map (a PNG file that allows us to trick 3D engines into making low-poly meshes look like they’re high-poly) for the final model. In Blender, this involves the sculpting tools. Tutorial

Retopologizing

Retopologizing is creating a new low-poly version of your mesh based on the high-poly version. This low-poly mesh /will/ be the final version, the one that you use in your game. Tutorial

Generating a Normal Map

Your new retopologized low-poly mesh will use a normal map which makes it look mostly like the high-poly version, but perform better. You’ll need the new low-poly and the high-poly versions of your mesh to create the normal map. Tutorial

Creating / Applying / Animating a Rig

A rig is a sort of virtual skeleton running through your mesh. Each bone in the skeleton moves part of your character model. By animating the skeleton, you animate the mesh. Simple Tutorial, Advanced Tutorial

Exporting the Final Result

When you’ve gotten your mesh retopo’d, mapped, and animated, it’s time to export. You’ll select the 3D file format according to your needs: the 3D engine you’re going to be using the mesh in and the sort of device the software will run on. (For example, MD5 isn’t very suitable for mobile at the time of writing, due to the heavy CPU cost of skeletal animation.)

Blender is an intimidating tool, but with the right instructions, everything falls into place. As a final note, when all else fails, ask an expert. The kindly folk in the #blender channel at Freenode.net are absolutely fantastic and have helped thousands navigate the Blender learning path.

Note: SOUR was created during my time with Kumoshi.

Our custom 3D format, SOUR, has gotten an upgrade. SOUR now has the capability to include “attachment points”, which will allow us to put things in avatars’ hands, things on their heads, etc. Behold:

sour2_1

The mechanism is pretty simple. See the red and blue dots? Their positions get saved alongside the animation keyframes. Moving the attached objects with them is as simple as telling the attached object to “go” to the red one and “look” at the blue one. Of course, the red and blue dots needn’t actually be shown.

Working on a game or 3D project that could use this sort of functionality? Check out SOUR’s Github page.

SOUR is a custom 3D file format designed to bridge the gap between Blender and Away3D. Aren’t there other formats which Blender exports and Away3D reads? Yes there are: OBJ, 3DS, MD2, MD5, AC3D, DAE. However, none of these formats except for DAE can save vertex tangents, and the DAE export script for Blender doesn’t save them.

What are vertex tangents, and why do they matter? Let me break it down.

What’s a Vertex Tangent?

You may know that 3D models are made of triangles. Each triangle has three points, called vertices. A vertex is a point in 3D space. Like a point in 2D space, a vertex has an X and a Y coordinate, but for 3D space, a vertex also needs a Z coordinate. There is other information related to each of a triangle’s three vertices too. I won’t go too deep into it except to say that the other information is used to light the 3D shapes correctly, and that part of that information about each vertex includes a second set of three numbers called a “vertex tangent”.

Vertex tangents are very important for “normal mapping”, a technique used to make a low-detail version of a 3D model look like it’s a high-detail version. Using normal mapping reduces the amount of power your graphics card needs to render a given 3D model, and thus increases performance without sacrificing much quality.

Back to Away3D and SOUR

Since none of the currently existing Blender export formats save vertex tangents, when Away3D reads the models, it realizes that there are no vertex tangents and attempts to figure them out itself. This is all well and good if the program used to create the 3D model’s normal map and Away3D are using the same vertex tangent generation math. Blender and Away3D don’t. The result is ugly seams on models using normal maps.

sour1_1

SOUR solves this problem by saving vertex tangent information into the 3D file. Away3D never gets a chance to generate (not incorrect but) mismatching vertex tangents, and the models look spiffy.

sour1_2

SOUR has a few other features too:

  • indexed & compressed to save space
  • bone or keyshape-based vertex animation
  • also exports vertex normals
  • has a Blender export script, an Away3D parser, and a Github page

If you do a Google search for “normal map seams”, you’ll find that Away3D isn’t even remotely the only engine which suffers from the nonstandard normal map generation problem. JMonkey, OGRE, XNA, and others all have this issue. I would love to see SOUR used more widely. If you have any suggestions for the format, leave them in the comments.