Self-made normal maps
How to create normal maps (bumpmaps) with Blender
Summary
Published January 06 2023 by @manavortex Last documented update: January 20 2024 by @manavortex
This guide will teach you how to create a custom normal map.
Wait, this isn't what I want!
For a different guide about this, check this Google Doc by Тима (Teem)#3118
For a guide on Cyberpunk materials in Blender, see Cyberpunk Shaders in Blender
If you want to create a
.mlmask
instead, see Textures: Custom .mlmaskOtherwise, you can use the wiki's search function — it uses an LLM and is actually quite useful.
Prerequisites
Version
Blender>= 3.6 (working on 4.0)
Assumed skill level
You know what a normal map is
You're able to draw stick figures
You are not afraid of Blender
You know how to read.
Step 0: Preparing the viewport
Export your mesh from WolvenKit
Import it into Blender (do not import materials)
Select the object
Make sure your material has exactly one material (see the end result in the screenshot at step 5):
if there are no materials: Awesome, you passed the reading comprehension test! Create one by clicking the
+
button.If there are materials: You failed the reading comprehension test and I am very disappointed. Delete all but one by selecting them and clicking the
-
button.
Assign a material to the only remaining slots:
Switch to the "Shading" perspective and add an "Image Texture". Select your image by clicking the corresponding button:
The viewport should already be set to "Solid". Click on the dropdown arrow next to the options and select "Texture" from the list.

Step 1: The Displacement Map
As the first step, we create a Displacement Map for our 3d object. This black and white image will turn your mesh into an object with actual (simulated) depth, which we will then "bake" into a normal map.

The displacement image should be saved in 32 bit image depth rather than the usual 8. This will yield better results with the normal maps.
Texture Paint Mode
The Texture Paint perspective lets you draw directly on your mesh's surface:

UV edit mode
To see how the mesh is projected on your image, you can check out the UV edit mode.
Switch to "Edit" (shortcut: Tab) and select all vertices (shortcut: ctrl+A). You will now see them projected on the texture:

Step 2: High Poly and Low Poly meshes
Once you are done with your displacement map and the UV mapping looks like you want it to, it's time for the next step: projecting!
Take your displacement map and create a slightly blurry version of it. This will prevent artifacts on the normal map, as the algorithm doesn't like perfectly straight edges.
Make sure that your viewport is in Object Mode
Select all objects that you want to go on the same normal map, then join them together (shortcut: Ctrl+J).
Create a duplicate of this mesh (Ctrl+D, ESC to stop moving), then rename that to "Low Poly".
Select the mesh you duplicated and rename it to "High Poly".
Open the "Modifiers" tab and assign the following modifiers after the armature modifier (check screenshot in Step 6)
Generate -> Subdivision Surface Levels Viewport: 2 or so Render: As many as Blender lets you get away with without crashing, I used 7 Advanced: UV Smooth: Keep Corners, Junctions Boundary Smoothing: Keep Corners
Deform -> Displace Coordinates: UV UV Map: UVMap Direction: Normal Strength: -0.002 (you can play around with this) Midlevel: 0.000
For the "Displace" Modifier, create a new picture, then click on the two sliders to show this texture in the textures tab
Load your blurred texture:
If you hide your "Low Poly" mesh, the modifiers should now let you see creases on your high poly object! Exciting!!
Step 3: Prepare the material
Switch to the "Shading" perspective again. Add another image texture and create an image with your target resolution. Call it "Bake" or whatever.
Remove the link to your material's normal input - otherwise, it'll bake your normal map into your normal map, and the results won't be pretty.

Step 4: Prepare the low poly mesh
The high poly mesh needs to be completely covered by the low poly one, like plastic wrap. That will normally not be the case yet, so we need to inflate the poly mesh:
Set the viewport to Object Mode
Select the Low Poly mesh
Switch into Edit Mode (Hotkey:
Tab
)Select all vertices (Hotkey:
ctrl+A
)Optional: Merge by distance (Hotkey:
M
)Fatten (Hotkey:
Alt+S
, adjust amount of fattening via mouse or by typing it in directly)Fix up whatever parts didn't fatten correctly by hand.
If your mesh inflates asymmetrically
Undo your action and select all vertices again.
Put the 3d cursor in the center of the selected vertices:
Right-Click -> Snap Vertices -> Cursor To Selected
Set the Pivot Point to 3D cursor (Shortcut:
.
(dot),Numpad 6
)Set it to "3D Cursor" Fatten again!
Step 5: Baking
Switch back to Object Mode.
In Blender, the "active" object is the "previously selected" one. Select your meshes in the following order:
Low Poly
High Poly
Find the "Render Properties" tab.
At the very top, set "Device" to "GPU Compute" (unless you'd rather bake on your CPU)
Scroll down all the way to "Bake". Configure it like this:
Bake Type: Normal
Influence / Space: Tangent
Selected to Active: Checked
Extrusion: 0.04 m If your generated normal map shows artifacts, try tweaking this.
Max Ray Distance: 0.04 m If your generated normal map shows artifacts, try tweaking this.
Output / Target: Image Textures
Clear Image: Checked
Margin / Size: 16px (or whatever suits you)
Save. Your. File.

If everything went well, the image editor on the bottom left will change and display your normal map.

You can export the image via the hamburger menu in the image editor (bottom left panel of the screenshot).
Step 6: No baking, only photoshop
So your baking process failed horribly and you're frustrated. Fair, I've been there — 3d edits are finicky. Let's do it in photoshop instead.
Load your black and white image into the photo editor of your choice (Photoshop or Photopea).
From the menu, select Filter -> 3d -> Normal Map (Generate Normal Map) in Photoshop)
Photoshop: Click "OK" on the popup (about the 3d features being outdated)
Tweak the parameters until you have a normal map — you want it to be as sharp as possible without artifacts/tearing! Some blur might be necessary.
Click "OK" to apply the changes.
Congratulations, you now have a normal map.

Troubleshooting
My normal map has yellow stripes!
Make sure to remove the normal mapping from your material.
My normal map has yellow spots!
First of all, make sure that all your normals are pointing the right way. In the viewport editor, click the "Show Overlays" button and select "Geometry -> Face Orientation" near the bottomn. Blue means outside, red means inside.
The baking process works by capturing the rays of light that bounce between the high poly mesh and the low poly mesh. If you have artifacts, then some of those rays bounced off something else first, which makes them register as inverted. That's the reason why steep creases are a problem — a ray of light might get caught in there and be flipped around.
Check the troubleshooting step for artifacts.
My normal map has artifacts!
Make sure your displacement map (the one used by the modifier) is blurred.
Try lowering the strength of the Displace modifier on the High Poly mesh, making the creases more shallow.
Try changing Extrusion and Max Ray Distance in the Bake settings.
If that doesn't help, you could try a cage, or otherwise hit Google.
Blender complains about my meshes
Restart Step 4 and make sure that you haven't deleted or altered any vertices, other than scaling/inflating the low poly mesh.
My normal map is inverted on one side
Here is an example of the issue :
Open the UV of your 3D model and select the vertices that are outside on the left of your UV


Now you have two separate submeshes. Export them both into the same .glb file for Wolvenkit.
Open Photoshop, Paint.net or Photopea to invert the green channel. Save your new .png under a name like <name_inverted_n>

Import your inverted normal map in Wolvenkit. Now, you can create a new material for the normal-inverted parts of your mesh!
Last updated
Was this helpful?