← Back to blog
Apr 20, 2026GuideBy Funplay AI

How to Generate a Normal Map from a Diffuse Texture

Generating a normal map from a diffuse texture converts color information into surface detail data that lighting shaders can read. This process uses height estimation from pixel brightness to create tangent-space normal maps that add depth and dimension to flat surfaces without extra geometry.

What This Process Does and Why It Matters

Normal maps fake surface detail on low-poly meshes by encoding direction vectors into RGB channels. Instead of modeling every brick, scratch, or fabric weave, you bake that information into a texture that the GPU evaluates per pixel. The result looks detailed under dynamic lighting without the performance cost of additional vertices.

The normal-map skill from Funplay Skills automates this conversion. It takes a diffuse PNG as input and outputs a tangent-space normal map. The tool depends on sharp, a high-performance Node.js image processing library. The output is engine-agnostic, meaning it works in Unity 2022.3 or later, Godot 4.2 or later, and Cocos Creator 3.8 or later without format conversion.

This matters for production pipelines because manual normal map authoring takes time. Programmers and tech artists can integrate this step into automated asset workflows. The Funplay Skills suite includes 12 skills total, and normal-map fits into a broader material preparation pipeline alongside texture-atlas planning and engine-specific prefab workflows.

The Material Prep Workflow

The normal-map skill sits in the middle of a standard material preparation pipeline:

  1. Start with a diffuse PNG exported from your source art.
  2. Run normal-map to generate a tangent-space normal map.
  3. Feed both textures into your engine's material setup through the appropriate engine MCP.

This flow connects to engine-specific tools like Unity MCP with its 79 tools, Godot MCP with 105 tools, or Cocos MCP with 67 tools. Each MCP handles the material creation, shader assignment, and property configuration on its respective platform.

Prerequisites

Before running the normal map generation:

  • Node.js installed on your system
  • sharp package available (installed as a dependency)
  • A diffuse texture in PNG format with clear tonal variation
  • Funplay Skills server running, accessible at 127.0.0.1 port 8765

The diffuse texture quality directly affects the normal map output. Textures with strong contrast between raised and recessed areas produce cleaner results. A stone wall with deep grout lines between bright stone faces works well. A nearly uniform surface produces weak normals.

Step-by-Step Walkthrough

Here is a concrete example using the command line to invoke the normal-map skill through the Funplay Skills MCP server.

Step 1: Start the Skills Server

Launch the Funplay Skills server. The server binds to 127.0.0.1 port 8765 by default.

# Start the Funplay Skills MCP server
node funplay-skills-server.js

# Server logs should confirm binding
# > Funplay Skills listening on 127.0.0.1 port 8765

Step 2: Prepare Your Diffuse Texture

Place your diffuse texture in a known directory. The file must be a PNG. For this example, assume the file is assets/textures/stone_wall_diffuse.png.

The image should have: - Clear light and dark areas representing height differences - Minimal baked lighting or shadows that could confuse height estimation - Sufficient resolution for your target detail level

Step 3: Invoke the Normal Map Skill

Send a request to the MCP server to generate the normal map. The exact method depends on your MCP client setup. Here is an example using a direct JSON-RPC call:

{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "normal-map",
    "arguments": {
      "inputPath": "assets/textures/stone_wall_diffuse.png",
      "outputPath": "assets/textures/stone_wall_normal.png",
      "strength": 2.0
    }
  },
  "id": 1
}

The strength parameter controls how pronounced the surface details appear. Start with 1.0 for subtle effects. Increase to 2.0 or 3.0 for more dramatic depth. Values above 5.0 often produce artifacts.

Step 4: Review the Output

Open assets/textures/stone_wall_normal.png. A correct tangent-space normal map has these visual characteristics:

  • Predominantly blue-purple base color (neutral normals pointing away from the surface)
  • Green and red variations where surface angles change
  • No residual color information from the diffuse texture
  • Clean edges without aliasing or fringing

If the output looks flat or washed out, increase the strength parameter. If you see banding or pixelation, your source diffuse may lack tonal range.

Step 5: Integrate with Engine Material

Feed both the diffuse and normal map into your engine. Using Unity MCP as an example:

// Unity material setup pseudocode
Material mat = new Material(Shader.Find("Standard"));
mat.SetTexture("_MainTex", diffuseTexture);
mat.SetTexture("_BumpMap", normalTexture);
mat.EnableKeyword("_NORMALMAP");

The exact steps differ by engine. Godot MCP and Cocos MCP have equivalent material creation tools within their respective tool sets.

Integration with Cross-Skill Workflows

The normal-map skill does not operate in isolation. It fits into a larger art import pipeline documented in the Funplay Skills workflow.

Material prep pipeline: Diffuse PNG → normal-map → engine material setup via MCP.

Extended art pipeline: Raw PSD export → sprite-sheet (slice frames) → texture-atlas (plan layout) → ui-slicing-checklist (verify nine-slice settings) → engine prefab workflow.

For materials specifically, you might generate the normal map first, then use texture-atlas to plan how multiple material textures pack into atlases for batched draw calls. Each skill hands off structured data to the next.

The /engine-workflow command helps select the correct engine-facing skill before modifying project files. This prevents common errors like importing assets with wrong settings or breaking existing material references.

Gotchas and Limitations

Normal map generation from diffuse textures has real constraints. Acknowledge them to avoid wasting time.

Source texture quality matters most. If your diffuse has baked ambient occlusion, color variation, or painted shadows, the height estimation reads those as surface detail. The result looks wrong under dynamic lighting. Clean, unlit diffuse textures produce the best normal maps.

Not a replacement for authored normals. A skilled texture artist baking normals from high-poly geometry produces superior results. Automated conversion from diffuse data approximates height from brightness. That approximation works for organic surfaces like stone, fabric, and leather. It fails for hard-surface mechanical parts where normal direction does not correlate with color brightness.

Tileable textures need careful handling. If your diffuse tiles, the generated normal map must also tile. Check the edges of your output for seams. Process the texture at the same tileable resolution as your final material.

Tangent-space only. This skill generates tangent-space normal maps. Object-space or world-space normals require different tooling. Most real-time rendering pipelines use tangent-space normals, but verify your shader expects this format.

Performance is not instant. Processing large textures (4096x4096 and above) takes time. The sharp library handles the computation efficiently, but do not expect millisecond turnaround on large assets. Build this step into your batch processing pipeline rather than running it interactively during gameplay development.

No specular or roughness generation. This skill produces normal maps only. You still need separate workflows for metallic, roughness, ambient occlusion, or other PBR texture channels.

When to Use This Tool

Use the normal-map skill when: - You have diffuse textures without authored normal maps - You need quick material prototypes with surface detail - Your art team lacks bandwidth for manual normal baking - You work with scanned or photographed textures that already encode height as brightness

Do not use it when: - You have access to high-poly source geometry for proper baking - Your diffuse texture has significant baked lighting - You need object-space or world-space normal maps - The surface detail does not correlate with color brightness (like a painted metal panel where color is decorative, not structural)

Related Skills in Funplay

The normal-map skill is one of 12 skills in the Funplay Skills suite. Other relevant skills for material and texture work include:

  • sprite-sheet: Slice sprite sheets into individual PNG frames
  • texture-atlas: Plan 2D atlas grouping, padding, naming, and manifest generation
  • ui-slicing-checklist: Verify UI sprite exports for nine-slice, pivot, and padding

These skills chain together for complete art processing pipelines from raw exports to engine-ready assets.

Next Steps

Connect the normal-map skill into your material prep workflow and test it on a sample diffuse texture. Then explore the full Funplay Skills repository for additional pipeline automation tools.

Resources: - Funplay Skills repository: https://github.com/FunplayAI/funplay-skills - Funplay Unity MCP: https://github.com/FunplayAI/funplay-unity-mcp - Additional game development guides: https://gamebooom.ai/en/blog/

Keep reading

Try it in your project. All four repos are on GitHub under github.com/FunplayAI — pick the engine you're using and follow the README.
How to Generate a Normal Map from a Diffuse Texture | funplay mcp