Baking Blender materials to texture to make them usable in a game engine

Or…

How to take a Blender model you downloaded from the web and make it actually usable in your game in 28 easy steps!

… granted, the second title doesn’t have the same flow to it, does it?

I just had to run through this process and I figured I would share it as it is something that occurs fairly often.  When working with Blender, there are dozens of behavioural textures available that can make for some very nice results quickly.  The only problem is, when you get your asset out of Blender and into your game engine, things suddenly go horribly wrong.  The problem is, those textures only make sense inside of Blender.  Fortunately through the magic of baking, you can easily convert them into a texture map usable in any game engine.

Let’s take a look how.

First we need a model.  I am using a beautiful new model that was recently added to Blend-Swap.  It’s a free download but you need to register.  Don’t worry, you can use a real email address, they don’t spam, or at least haven’t so far.  The model in question looks like this:

image

Unfortunately when we load it in Blender we quickly learn this model is in no way game ready.  Let’s take a look:

image

Ick.  So instead of a single Mesh, we have a dozen individual meshes.  Problem is, we need to unwrap them as a single object, so let’s join them all together.  First let’s get the camera out of the default layer.

If you look at the way this particular Blend is setup, there are currently two layers, the second contains the armature, the first contains everything else.

image

Lets get the camera out of there.  Select the camera object then hit the M key.  Then select the layer you want to move the camera to, like so:

image

Now click the first layer ( bottom left box ) and it should now only contain geometry.

We want to join everything together.  Press ‘A’ to select everything in the layer, then hit “Ctrl + J” to join everything into a single set of geometry.  Now it should look something like this:

image

Perfect, now we can unwrap our model.  Switch in to EDIT mode

image

Press ‘A’ again, until all faces are selected, like so:

image

Now we unwrap our model.  Select Mesh->UV Unwrap-> Unwrap ( or Smart UV Project ).

Switch your view to UV/Image Editor

image

It should look something like this:

image

Now create a New Image:

image

This image is where we are going to render our texture to.  Here are the settings I used.  Remember, games like Power of 2 textures.

image

Ok, now let’s look at the actual render to texture part.  Take a quick look at how the model is currently shaded:

image

Frankly none of those are really game engine friendly.  So let’s render all of those materials out to a single texture.  Go to the render tab

image

Scroll down and locate Bake.

In the UV Editor window, make sure everything is selected ( using ‘A’.  They should be highlighted in yellow ).  At this point, with your generated image and all the UV’s selected, it should look like:

image

Now under bake, set the following settings:

image

The key values being Bake Mode = Full Render and Selected to Active checked.  Now click the Bake button.

Up in your top part of Blender, you should see a progress bar like so:

image

Now if you go back to the UV/Image viewer, and select your image RenderedTexture, you should see:

image

Cool!

Let’s save the result to an external ( game engine friendly ) texture.  Select Image->Save as Image.  Save the image somewhere.  Remember where.

image

Now lets modify the textures on our model to use only our newly generated texture map.  First in 3D View, switch back to Object Mode from Edit mode.

Then, open the materials tab:

image

Select each material and hit the – ( or killswitch engage! ) button.  So it should ultimately look like this:

image

Now hit the + button and create a new Material.  Then click the New button.

image

The default values for the material should be OK, but depending on your game engine, you may have to enable Face Textures:

image

Now click over to the Texture tab.  Click New.

image

Drop down the Type box and select Image or Movie.

image

Scroll down to the Image section and select Open.  Pick the image you saved earlier.

image

Now scroll down to Mapping, drop down Coordinates and select UV.

image

Under Map select UVMap.

image

Now if you go to the 3D View and set the view mode to Texture:

image

TADA!  A game ready model.

One word of caution though, if you render this scene in Blender you will get the following result:

image

Don’t worry.  That’s just a biproduct of going from Blender materials to texture mapping.  If you want the texture to be seen, you need to add some lights to the scene.  Or change the material so it has an Emit value > 0, so it will provide it’s own light source.

With Emit set to .92, here is the result if you render it:

image

Now, what about it game?

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Files.FileType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader;
import com.badlogic.gdx.utils.UBJsonReader;


public class ModelTest implements ApplicationListener {
    private PerspectiveCamera camera;
    private ModelBatch modelBatch;
    private Model model;
    private ModelInstance modelInstance;
    private Environment environment;

    @Override
    public void create() {
        camera = new PerspectiveCamera(
                75,
                Gdx.graphics.getWidth(),
                Gdx.graphics.getHeight());

        camera.position.set(3f,0f,6f);
        camera.lookAt(0f,1f,0f);

        // Near and Far (plane) represent the minimum and maximum ranges of the camera in, um, units
        camera.near = 0.1f;
        camera.far = 300.0f;

        modelBatch = new ModelBatch();

        UBJsonReader jsonReader = new UBJsonReader();
        G3dModelLoader modelLoader = new G3dModelLoader(jsonReader);
        model = modelLoader.loadModel(Gdx.files.getFileHandle("robot.g3db", FileType.Internal));
        modelInstance = new ModelInstance(model);

        environment = new Environment();
        environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.8f, 0.8f, 0.8f, 1.0f));
    }

    @Override
    public void dispose() {
        modelBatch.dispose();
        model.dispose();
    }

    @Override
    public void render() {
        Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

        camera.update();

        modelBatch.begin(camera);
        modelBatch.render(modelInstance, environment);
        modelBatch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}

And we run it and:

image

Wow, a model downloaded randomly from the Internet actually working in the game engine!  How often does that actually happen? 😉

Scroll to Top