Skip to content
← Back to Blog 3d-modeling

PBR Texture Baking in Blender: AO, Roughness, Metallic, and Emission for Game-Ready Assets

By BitSoul3D7 min read266 views

Most game artists bake normal maps and call it done. But the difference between a flat-looking asset and one that reads convincingly in any lighting comes down to your full PBR texture suite — AO, roughness, metallic, and emission baked correctly and packed efficiently. This guide walks through the complete multi-channel bake workflow in Blender, from scene setup through export-ready textures for Unity, Unreal Engine 5, and Godot 4.

PBR Texture Baking in Blender: AO, Roughness, Metallic, and Emission for Game-Ready Assets

Setting Up Your Bake Scene in Blender

A clean bake starts with a clean scene. Before you open the Render Properties panel, get these five things right:

Render engine: Switch to Cycles. Eevee cannot bake. Set Device to GPU Compute if available — bakes run 5–20× faster on GPU.

High-poly and low-poly workflow: If you're baking detail from a high-poly mesh, make sure both meshes share the same origin point. Name them clearly (MyProp_high, MyProp_low). In the Bake panel, enable Selected to Active and set an Extrusion value of 0.01–0.05m depending on mesh complexity.

UV maps: Every mesh you bake must have a non-overlapping UV layout in the channel Blender will write to. Add a second UV map (UVMap_Bake) if your material UVs are tiled or overlapping. Select the bake UV map as active before baking.

Image node setup: In every material on the low-poly mesh, add an Image Texture node (Shift+A → Texture → Image Texture), create a new 2048×2048 or 4096×4096 image with 32-bit float enabled for AO and roughness bakes, and select that node WITHOUT connecting it to any other node. Blender bakes into whichever Image Texture node is selected, not connected.

Bake margin: Set Margin to at least 16px at 2K resolution to prevent texture bleeding across UV islands at runtime MIP levels.

Setting Up Your Bake Scene in Blender — illustrated

Baking Ambient Occlusion and Roughness Maps

AO and roughness require different node setups before baking.

Ambient Occlusion

AO is the simplest bake — select the target Image Texture node in each material, set Bake Type to Ambient Occlusion, and hit Bake. No special node wiring needed. However, tune these settings first:

Roughness

Roughness is a Emit bake — you wire your roughness value into an Emission node and bake as Emit. This lets Blender write any procedural or texture-driven roughness value directly to the image:

# Blender Python — set up roughness bake node chain
import bpy

for mat in bpy.data.materials:
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links

    # Find the BSDF
    bsdf = next((n for n in nodes if n.type == 'BSDF_PRINCIPLED'), None)
    if not bsdf:
        continue

    # Add emission node
    emit = nodes.new('ShaderNodeEmission')
    emit.location = (bsdf.location.x - 200, bsdf.location.y - 200)

    # Connect roughness socket output to emission color
    rough_input = bsdf.inputs['Roughness']
    if rough_input.links:
        rough_node = rough_input.links[0].from_node
        rough_socket = rough_input.links[0].from_socket
        links.new(rough_socket, emit.inputs['Color'])
    else:
        # Constant roughness — drive through value node
        val = nodes.new('ShaderNodeValue')
        val.outputs[0].default_value = rough_input.default_value
        links.new(val.outputs[0], emit.inputs['Color'])

    # Wire emission to output
    out = next(n for n in nodes if n.type == 'OUTPUT_MATERIAL')
    links.new(emit.outputs['Emission'], out.inputs['Surface'])

After the Emit bake completes, rewire the output back to the BSDF — the script above connects temporarily for baking only.

Save the AO image as a 16-bit PNG (lossless). Save roughness as 8-bit PNG — it doesn't need float precision.

Baking Metallic and Emission Channels

Both metallic and emission use the same Emit bake approach as roughness.

Metallic

Metallic is a binary value in most PBR workflows (0.0 = dielectric, 1.0 = metal), but parts of an asset may blend — painted metal, rusted areas, or worn edges. Bake it the same way: wire the Metallic socket output into an Emission node, set Bake Type to Emit, bake, then restore the original node graph.

If your metallic value is a constant (e.g. the whole mesh is metal or all dielectric), don't bake it — just set the metallic value to 0 or 1 in Unity/Unreal directly and skip the texture slot entirely. You'll save memory and a sampler.

Emission

For glowing parts — screens, lava cracks, neon trim — bake emission directly:

  1. Set Bake Type to Emit
  2. Wire only the emission color into the material output (disconnect the BSDF)
  3. Bake to a dedicated emission image
  4. In Unity/Unreal, assign this as your emissive texture and enable bloom as needed

Important: If non-emissive parts of the mesh have a black emission (the default), those areas bake to pure black correctly — no masking needed.

Emission — illustrated

Channel Packing Your Bakes for Unity, Unreal, and Godot

Each engine expects textures in specific channel layouts. Packing multiple maps into one RGBA image cuts texture memory and sampler count — essential for mobile and Quest targets.

EnginePacked TextureRGBA
Unity (URP/HDRP)Mask MapMetallicAODetailSmoothness
Unreal Engine 5ORMAORoughnessMetallic—
Godot 4ORMAORoughnessMetallic—

Note: Unity's Mask Map uses Smoothness (1 - Roughness), not Roughness directly. Invert your roughness bake before packing for Unity.

Pack channels in Blender's compositor or use this Python snippet post-bake:

import bpy
from mathutils import Vector

# Pack AO (R), Roughness (G), Metallic (B) into ORM image
ao_img   = bpy.data.images['bake_ao']
rough_img = bpy.data.images['bake_roughness']
metal_img = bpy.data.images['bake_metallic']

width, height = ao_img.size
orm = bpy.data.images.new('ORM_Packed', width, height, alpha=False)

ao_px    = list(ao_img.pixels)
rough_px = list(rough_img.pixels)
metal_px = list(metal_img.pixels)
orm_px   = [0.0] * len(ao_px)

for i in range(0, len(ao_px), 4):
    orm_px[i]   = ao_px[i]      # R = AO
    orm_px[i+1] = rough_px[i]   # G = Roughness
    orm_px[i+2] = metal_px[i]   # B = Metallic
    orm_px[i+3] = 1.0           # A = 1.0

orm.pixels = orm_px
orm.filepath_raw = '//textures/ORM_Packed.png'
orm.file_format = 'PNG'
orm.save()

This gives you a single ORM texture compatible with Unreal Engine 5 and Godot 4 out of the box.

Exporting and Verifying Your Baked Assets

Once textures are baked and packed, run through this checklist before committing to your project:

You can find a growing library of game-ready assets with correctly baked PBR textures on BitSoul's marketplace — each asset ships with separated AO, roughness, metallic, and packed ORM textures where applicable, saving you hours of bake time on common prop types.

Putting It Together: The Full Bake Pipeline

Here's the complete bake order for a hero prop, from clean mesh to engine-ready textures:

  1. UV unwrap the low-poly with adequate margin (at least 4px/texel at target resolution)
  2. Bake Normal map first (Cycles, Selected to Active if using high-poly)
  3. Bake AO — 128 samples, Local Only, Distance tuned to asset scale
  4. Set up Emit bakes for Roughness, Metallic, and Emission via node chains
  5. Channel pack into ORM (Unreal/Godot) or Mask Map (Unity) using the compositor or script
  6. Verify color spaces — all data maps to Non-Color before export
  7. Import to engine, assign textures to the correct slots, and light-test under multiple HDRIs

This pipeline keeps your texture memory efficient and your draw calls low — critical for any real-time target. For assets you plan to sell or distribute, the baked texture quality is the first thing buyers evaluate. Properly baked PBR maps that hold up under studio lighting and dynamic environments are what separate professional marketplace assets from hobbyist uploads.

Browse professionally prepared, engine-ready 3D assets with complete PBR texture sets at BitSoul's marketplace — and if you're uploading your own work, use this bake checklist to make sure every texture ships clean.


Need drop-in assets for this workflow? Grab the Architecture Cyber Bundle on the BitSoul marketplace and drop them straight into your project.

Tags: architecture

Skip the modeling — download it instead

A free BitSoul3D account gets you 2 GLB downloads every month for personal use plus 25 one-time AI Engine credits, no card required. PBR-textured GLB downloads with a full 3D preview before you buy, for Unreal, Unity, Godot or Blender — OBJ and 3D-printable STL come with any purchase or paid plan.

Browse 1,051 models — from $4.99 → or start free (2 downloads a month)