Tutorial: Making Isometric Sprites out of 3d models with Blender

(1/4) > >>

Rock D:
If you are making a game in isometric perspective, you might notice that it can require quite a lot of art because characters need to be animated doing their thing facing many directions instead of just 1. A classic way of quickly making a lot of isometric art is prerendering 3d models in isometric perspective. Diablo and Fallout are two well known games that use this technique.
I have made a blender file with a camera setup that helps you render 3d models in isometric perspective from a number of directions. It even supports animations. Here is an example:

Download it here

Version log:
- 101: Changed the perspective angle to actually be 2:1 (with the option to use true isometric)
- 102: Added a static model to use in the second tutorial and fixed the IpoLoop script to loop more properly (without interpolating between loops, but still enabling interpolation within loops).
- 104: Added a script to make a sprite sheet out of the frames (many thanks to Angelo Theodorou for that). Added a guide on how to use scaling as an anti-aliasing filter.

There is a readme included that should be straightforward enough to let novice Blender users use it. If you are completely new to Blender, I do recommend following the Blender user interface tutorial first. Blender's interface is very unintuitive. It even hides vital functionality under hotkeys with no way of discovering it exists through a menu or toolbar. Another useful thing to know is that Blender will never ask you to save on exit regardless whether you've made changes to your file. On the plus side, the interface is very customizable, so once you know about the quirks, you can set it up exactly how you like it.

I have included 2 python scripts to ease customizing the settings. 'CamCircleStops' animates the currently active camera to circle the origin in a set number of steps, optionally stopping for a while at each direction to let a looped animation play out.
'IpoLoop' lets you loop the animation of the currently selected object for the duration of the camera animation.
The 'strip_render' script has instructions on how to render the frames together into one sprite sheet.

Introductory Tutorial: Rendering a static model in 32 directions.

1: This is what you'll see when you open the file.

On the top left there is an overview of the stage area, where you can see the the camera and a light pointed at the origin. On the top right is the view as seen from the camera. You can change the current frame and see the camera and its view animate by clicking and dragging over the timeline, the area in the middle of the screen.
Bottom left contains the scene panel, where you can set where you want to put the resulting files, change the file format and resolution of the render and do the actual rendering by clicking the ANIM button. On the bottom right there is a ReadMe in a text window, which you change to display the two included scripts with the button on the left of the TX:ReadMe label.

2: Let's add a model to the scene. While hovering the mouse over the top left window, press space. From the menu choose Add -> Model -> Monkey. This will place a monkey head model on the origin, where the scene cursor is (the red and white crosshair). You could also import your own model from various formats by opening the File -> Import menu.

3: The model isn't properly rotated and scaled to fit the frame. First rotate the model by pressing 'R', then 'X' to constrain rotation to the X axis, then enter '90' on the numpad and press enter.
Scale the model by pressing 'S' and moving the mouse until the model fits the dashed area in the upper right. Check that the model doesn't get outside of the frame for every frame of the camera animation by clicking and dragging over the timeline in the middle area of the screen.

4: We are almost ready to render the model. Check the output settings on the lower left. By default it will render in 128x128 png format to the directory c:\temp, prefixing each file with 'person'. To start rendering with these settings, press the 'ANIM' button. The render window will show a black background, but the resulting file will have proper alpha transparency to make an 'empty' background. I've made an animated png (that will only work in firefox) out of the first 8 of the 32 rendered frames of the result:

Advanced Tutorial: Animating a model using Blender Bullet physics and using the scripts to render the animation from all directions
There are many ways to animate a model in Blender, from simple transformations to using a bone armature. I'm going to use the built in physics engine to animate a simple figure losing his head. Then I'll make that animation loop every 10 frames with the 'IpoLoop' script and let the camera pause for 10 frames at every direction with the 'CamCircleStops' script.

The default view doesn't have the included model on it. Switch to its layer by hovering your mouse over the top left window and pressing 'Alt 1'. You can rotate around the model with 'Num 4,6,2 and 8' and zoom with 'Num + and -' or the scrollwheel.

Now we're going to make physics objects out of the model. Switch over the button panel view (down left) to 'Logic' by pressing F4 or clicking the purple smiley button in its toolbar. On the left, the purple buttons define the physics properties of the currently selected object. Select the head and then change the physical representation type (purple drop down menu on the top left) to 'Rigid body'

If you press 'P' while on the top left window, you can see the physics simulation play out. You've actually asked Blender to start a 'game' using your scene in that window.  Right now the head just wobbles a bit because the body of the person is set to 'static' and no forces are applied to the head. Press 'Esc' to exit the game mode. We can apply a force by using Blender's game object logic editor on the right of this panel.

First we add a sensor to the head by pressing 'Add' next to the head object listed under the 'Sensors' heading. The default is an 'Always' sensor that will output a high signal (true) every frame on the yellow port to the right of it.
Then we add a controller by pressing 'Add' next to the head object listed under the 'Controller' heading. I won't get into controllers here, the default setting should just pass through the signal on the left yellow input port to the right yellow output port. Link the output port of the sensor to the input port of the controller by clicking and dragging a line between them.
Lastly, press 'Add' next to the head object under the 'Actuators' heading. This should add a simple motion actuator by default, which we can use to apply a force to the head. Fill in -3 in the first value field (X-axis value) next to the 'Force' label. Then link the output of the controller with the input of the actuator. The result should look like this:

If you now press 'P' on the 3D view, you will see the guy losing his head as intended. Because the option 'Render Game physics to IPO' is checked in the Game menu in the upper menu bar, Blender will try to save the path objects take 'in game' due to physics as an animation for those objects. This is a bit flakey, for some reason it doesn't record the animation properly. The way to get it work is by using an undocumented feature (welcome to Blender!) that will bake the physics to an animation directly without starting the game engine by pressing 'Ctrl+Alt+Shift+P'. You can now see the animation play out by click-dragging your mouse over the timeline in the middle of the screen.

Let's take a look at how the animation is actually recorded in Blender. Switch the bottom left window over to the 'IPO curve editor' by clicking the button in its top left corner and selecting that from the menu. Both location and rotation values for all three axes over time are represented as bezier curves, also called IPO curves. A collection of IPO curves of an object is called an IPO. Like with objects in the 3d view you can scale and transform the curves with the 'S' and 'G' keys and constrain those operations to a certain axis with the 'X' and 'Y' keys. Just as with the timeline, you can click and drag over the graph to see how the scene works out in that frame.
Try scaling and transforming the curves (you can select them all at once with 'A') until you have an animation in the first 10 frames that you are satisfied with.

Now we can use the scripts to loop the animation and make the camera wait for them to play out at every direction. Switch the text editor window (bottom right) over to the 'IpoLoop' script by choosing that from the drop down menu that currently has 'TX:Readme' on it. Set the 'aniLen' variable in this script to 10. If you then press 'Alt P', this will run the script and loop the first 10 frames of animation of the currently selected object over and over for the duration of the camera animation. You can see the changes it made in the IPO editor.
For the camera, we change over to the 'CamCircleStops' script. This script will animate the 'currently active camera', so we have to change the active camera to the one in this layer by first selecting it and then, while hovering over the top right window, pressing 'Ctrl+Num0'. Since running the script destroys the animation the camera previously had you have to be careful what camera you run it on (same goes for the object animations when running the IpoLoop script). Make sure the 'aniLen' variable is set to 10 and press 'Alt P'.

Now we have successfully animated a model and the camera to render it to an isometric sprite. Switch the Ipo editor window back over to the button window, and the button window's game logic panel back over to the Scene panel. One last thing to note is that the 'CamCircleStops' script will automatically set the End frame number in the Anim tab to the value that will include the whole animation from all directions. This value isn't tied to the current camera you're using, so be sure to set it to the end frame of the animation of the currently active camera if you are switching between cameras in one file without running the 'CamCircleStops' script on it again. Here are 10 frames (1 direction) from the resulting render:

I am looking forward to your comments, critique, questions and feature requests.

Thank you!

Could you add a brief guideline and some screenshots? I think this way it would be more useful.

Is this true isometric or 2:1?

Rock D:
Quote from: BorisTheBrave on January 15, 2009, 05:42:58 am

Is this true isometric or 2:1?

Good question. It turns out I botched my calculations a bit, so it was neither. Now I've updated the file to use 2:1 by default and optionally true isometric.

Rock D:
I made a little robot dude. I turned off the anti aliasing for this (called OSA in blender) so you can see the characteristic 2:1 pattern at the sharp edges.

I am currently looking into making a script that will paste the whole bunch of rendered images you currently get as output into one spritesheet. Then again, maybe people prefer to use separated files for frames of animations nowadays? I also want to put in support for scaling down large renders to pixel art sizes, because that might give better results than how blender renders small targets.


[0] Message Index

[#] Next page