An Action-Arcade Experience in Your Browser. Play it now!
Site & Content © 2014-2015 by Mike Linkovich

Article: Normal Mapped Sprites

Part 1: Creating Normal Mapped Sprites with Blender

Note: This is not a Blender tutorial. If you're new to Blender, you really should go through some introductory tutorials first because its interface is not very intuitive. The instructions below are intended for people familiar with Blender who already know how to create models, matierals, renders, etc.

That said, if you're a new-ish user, here are tips that make things easier for me:

  • You can change the default mouse button functions! Go to File → User Preferences → Input, then change Select With from right to left.
  • I also prefer to move the camera with the right button rather than the middle button (which hurts my hand.) In that same preferences window, expand 3D View → 3D View (Global). Change Set 3D Cursor to middle mouse by clicking it then clicking the middle mouse button. Then change Rotate View, Move View, Zoom View and Dolly View to use the right button. Just be sure to hold the key modifiers down while changing these.
  • Presets also has the option to use 3DS Max and Maya configurations if you're more familiar with those.
  • Also consider enabling the Prompt Quit feature under the Interface tab, which will warn you to save before quitting.
  • Poke around in the preferences window to see if there's anything else that will make Blender easier for you to work with.

So, let's get started. First we'll create a template that can be used as a starting point for each new model (sprite) that you want to create.

  1. Set up render:
    • Properties panel → Render settings
    • Set Resolution X,Y (Might be a good idea to at least double the size you'll want for your final game artwork so you've got breathing room to scale it later. Display resolution just keeps increasing, after all.)
    • 100%
    • You'll probably want transparency around your model in the rendered image. Go to Shading → Alpha: Transparent.
    • Scroll down to Output and you can set the directory where the rendered image will save. Also be sure that PNG, RGBA and Color Depth:8 are selected.
    • If you want to set a background color, go to the World properties panel and set the 3 colors there (horizon, zenith, ambient.)
  2. Set up camera:
    • Tip: You can pull out a Transform panel by grabbing the plus (+) at the top right of the modeling view area. Otherwise activate the Object panel (cube icon) to see Transform data there.
    • Select the camera object in your scene, set Transform:
    • Location 0,0,5 (or as high as it needs to be so it's not clipping your model - you can adjust this any time.)
    • Rotation 0,0,0
    • Note the "up" direction of the camera so you'll know how to orient your model.
    • Properties panel → Camera
    • Lens: Orthographic
    • Orthographic Scale: This is the value you can adjust to crop the render area to the exact size you need to fit your model. Eg: using 2.0 will render the area [-1,-1...1,1] under the camera.

  3. Create a normal map material:
    • We'll do this early on so it's part of your Blender file. It could be awkward adding it after your model is complete and the diffuse image is rendered.
    • Download this image: normalmap-material.jpg. It's a key ingredient for creating a normal map material.

    • Select the default cube Blender added to the scene so you can add the material (or add one yourself.) We'll discard this model eventually but the material will be in the material library thereafter.
    • Create a new material. Call it "normals" or something like that.
    • Check Shadeless.
    • Go to the Texture panel (checkerboard, right of materials)
    • Add a new texture
    • Type: Image or Movie
    • Below, in the Image section you can choose an image file for the texture. Use the normalmap-material.jpg file linked to above.
    • Further down in the Image Mapping section, for Coordinates: select Normal.

  4. Finally, save this Blender file. From now on, you can use this file as a template to start new projects without going through all that setup work.
After we've got that template created, each new sprite can be created using the following process:
  1. Open the above Blender file. Immediately Save As a new file so you don't overwrite your template!
  2. Create/import your model:
    • Put the origin/pivot point of the model at 0,0,0 so it's centred directly under the camera.
    • Model Orientation: For "overhead view" types of games (eg. Asteroids) I render my sprites rotated 90° (PI/2 radians) clockwise (relative to the camera view.) This makes it easy to do x=cos(r), y=sin(r) in the game without needing to hack away at pre/post transform adjustments. For platformer/side-view types of games, you'll probably want to render sprites oriented normally (pointing up.) The point I'm trying to make here is that you will not be able to correct the rotation your images in Photoshop/GIMP after they are rendered! The normal map must be rendered using the default (0°) orientation you'll be using in-game, otherwise the lighting direction will be wrong. Be sure to use the same orientation for all renders!
    • As for model detail... go nuts! We're only going to be using the rendered bitmap in the game which can be rendered using just 4 vertices, no matter how detailed it is. So your model can have as much detail as you want to add. Use high-detail spheres and cylinders so the facets aren't visible in the render. You don't have to worry about optimizing geometry or deleting hidden polygons - all that matters is that it looks good from the top view. This is one of the perks of this process, so take full advantage of it. At the same time, remember that the sprite may end up being fairly small in-game so don't add detail you can't see and maybe do some test renders to scale to make sure it reads okay visually at that size.
  3. Create and apply shadeless, diffuse materials: (colors and textures)
    • The sprite that will be created from this model is going to be lit dynamically in the app. As such, you won't be able to apply any materials besides shadeless color materials. Light and shade will be generated at runtime!
    • Use the Diffuse color property for color and be sure to check the Shadeless checkbox in the Properties → Materials panel for each new material you add to the model. Don't worry about the other material settings; they'll be overridden by the shadeless option.
    • You can use textures for things like mud, rust, wood grain, camo patterns, etc. But again, only use regular textures; don't bother applying baked normal maps since that information can't be used. You'll have to model any 3D details you want to see dynamically lit.
    • Materials Tip: Each model has a set of materials (slots) assigned to it, which is a subset of all the existing materials you've created. To add multiple materials to a model, you have to create multiple slots. To assign materials to specific faces, you have to select the faces then click the Assign button to apply one of the materials in the slots.

  4. Render the diffuse texture:
    • Use Render → Render Image to render it. This is your diffuse texture. Save it with Image→Image Save As (the menu at the bottom.)

    • Check it out in a paint program to make sure that it worked out ok. The flat shading might look weird and crappy for now but be patient, the normal map will make everything better once the assets are in the game.
    • You can return to the model view by selecting 3D View from the little icon/menu thing near the bottom left of the image viewer.
  5. Then SAVE the Blender file!
    • We're going to change all the materials, so this would be a good time to make sure you've got a copy of the project with your diffuse materials saved.
  6. Apply the normal map material:
    • To the entire model. (Or at least to every part of it that will be visible from the top view.)
    • If your model is made up of multiple objects, you can select them all, then click the "down triangle" beside the material slots to use Copy Material to Others.
  7. Render again, to a new image file:
    • Disable Antialiasing - this is important, because while smoothing pixel colours works well for the diffuse texture, smoothing the normal values does not - it will give you undesirable hairline edges of unnatural lighting around your shape and between regions with different normal values.
    • Again use Render → Render Image to render and save an image. This is your normal map texture.
    • In a paint program, set the background colour to 127, 127, 255. (This is a neutral, "flat" plane that faces the camera, i.e. a normal vector of 0,0,1.) Then flatten and save it as a 24-bit RGB image.

    • To perfect this normal map image, it should have a few "bleed" pixels added around the edges of the sprite (pixels that are the same colour as the pixel at the edge of the sprite.) This will counteract the smoothing that OpenGL will apply to textures when scaling them or when using mipmaps. This is a bit tedious, as you'll need to make 8 copies of the normal map image on layers behind it, offsetting each one by 1 pixel in 8 directions around it. Then you'll need to repeat that process for as many bleed pixels as you want (which will depend on how much scaling in-game that you plan to do.) A scripted action would greatly help with this process.
    • Note that you don't want to scale your normal map images in a pant program. Ideally you should render them at the size they will be used, without anti-aliasing.

You may or may not want to save this project in its current state (with a different filename, of course) since you've removed all your diffuse materials from the model. Don't overwrite your previous save otherwise you'll lose all your diffuse material work!

Managing two sets of materials: Note that if you want to edit the model and change any geometry or diffuse materials, you'll have to go back to your diffuse materials project and go through the process of rendering the diffuse texture then applying the normal map material and rendering it all over again. Check out this thread for tips on how you might keep two separate instances of the same geometry with different sets of materials.

A note on specular (or other) effect maps: It's beyond the scope of this article, but be aware that you could create additional textures to indicate specular highlight areas or simple stuff like emissive lights, blinking, color-shifting lights, and other effects. You'd need to build these capabilities into your shader, but it's entirely possible to do. Creating those textures would be easier than the normal map; you could simply create a grayscale image with white areas indicating where those effects be applied (a good place to store this might be in the alpha channel of the normal map.) You could create this texture either in Blender with a different material set or create those textures directly in a paint program, using your diffuse texutre as a reference - whatever's easiest.

Other 3D Apps: I don't have 3D Studio or Maya, so I don't know what the process would be in those apps. Hopefully there are equivalent features that can accomplish the same thing.

Credit to Richard Marklew in the forums who explained how to create a normal map material (in this thread.)

Continue to Part 2: Normal Mapped Sprites with WebGL »

© by Mike Linkovich. Last updated Feb 16 2014.

comments powered by Disqus