Convert a photo or texture image to a normal map
Creating a normal map from an image starts with the browser decoder for PNG, JPEG, or WebP. The converter scales oversized sources to the free 2K limit and calculates luminance without a server round trip. A grayscale height source is the most predictable input, but a photo or color texture can be useful for fast material blocking when you understand that color changes may become false depth.
Local generation runs inside this browser. Your source image is not sent to Normal Map Studio, FAL, or another model provider unless you deliberately open an AI workflow and confirm the upload disclosure.
- Drag, browse, paste, or load the built-in procedural sample.
- Compare source and output without losing your current settings.
- Undo and redo parameter changes before export.
- Download one map or package the generated set as a ZIP archive.
Choose an input that produces cleaner normals
Even, diffuse lighting gives the luminance gradient a better chance of matching physical relief. Specular highlights, cast shadows, text, and color-only boundaries often create unwanted grooves. If you have a dedicated height map, use it. If you only have a photo, lower strength, add a small blur, and inspect the sphere preview from several light directions.
Seamless sources benefit from wrapped edges. Non-tiling photos usually look better with clamped edges because opposite sides do not describe neighboring texels. The edge option changes sampling during generation; it does not claim to reconstruct missing material outside the frame.
Export with the renderer in mind
Use the Unreal Engine preset for the common DirectX green direction. Unity projects may use either convention depending on texture import settings and render pipeline, so verify a small material first. Blender commonly expects OpenGL direction. Godot defaults can also depend on how the texture is imported, making the explicit format label more reliable than guessing from a filename.
Normal Map Studio exports ordinary PNG files. It does not apply engine-specific compression, because compression belongs in the destination project where color space, bit depth, and platform settings are known.