gizmobench

Normal Map Generator

Choose a height map, drop one onto the panel or paste an image, and it is converted here in the browser tab: a 3 by 3 Sobel gradient over the image's luminance, turned into a unit vector per pixel and packed into red, green and blue. The left panel shows the greyscale height field the converter actually reads, so a source that looks like a texture but carries almost no height variation is obvious before you download anything. Both Y conventions are one click apart, OpenGL with green pointing up the texture and DirectX with green pointing down it, and the border rule is a choice rather than a silent default: clamp repeats the edge pixel, wrap reads the opposite edge so a tiling texture keeps the slope across its seam. Images up to 20 megapixels are accepted, nothing is uploaded, there is no account and the PNG that comes out is the same pixel size as the file that went in.

height mapno image

no image yet

normal maptangent space

flat normal is 128, 128, 255

or drop one here, or paste an image

Never uploadedNo accountOpenGL or DirectXUp to 20 megapixels
Strength
2.0
Format
Edges
Size
no image
  • Flat grey, strength 4no height change anywhere
    flat normal 128, 128, 255, however hard it is pushed
  • A ramp at strength 2 and 4the same source, twice
    red 48 becomes 19: the same slope, tilted further
  • OpenGL against DirectXa ramp running down the image
    green 207 becomes 48, red and blue unchanged

Those three lines are printed by running the same code your image goes through, not typed in by hand.

Your image stays on this device. A Sobel gradient over the image's luminance, encoded as a tangent-space normal map. It derives slope from brightness, so it is only as good as the height data in the source; it is not a substitute for a sculpted map. There is no upload, no account and no watermark, and no image byte is handed to analytics either: the only thing the page records is that the tool was used.

Common questions

What kind of image works as a height map here?
A greyscale image where brightness means elevation: white stands high, black sits low. The converter reads brightness as height using the standard luminance weights, 0.2126 red, 0.7152 green and 0.0722 blue, so a grey level reads as exactly itself and a colour photograph reads the way brightness is perceived rather than as a flat average of the channels. A colour source is accepted and the page says on screen when the image is not greyscale, because a colour edge with no change in brightness stays flat and a dark colour reads as a valley. Transparency is not consulted at all: a normal map has no alpha channel to carry it, so the colour under a transparent pixel, usually black, is read as height like any other pixel. Flatten a cut-out onto a background first if you do not want a cliff at its edge.
Should I choose OpenGL or DirectX?
It depends on the renderer, and the two differ in exactly one thing: which way green points. OpenGL, and engines that follow it such as Blender, Godot and Unity, treat +Y as up the texture. DirectX, and Unreal Engine, treat +Y as down it. Pick the wrong one and the lighting looks inverted: bumps read as dents when the light moves. Switching the control here mirrors the green channel about the midpoint and leaves red, blue and alpha byte for byte identical, which is the whole difference between the two formats, and the convention you chose is printed beside the result and on the copied settings line so the file does not become anonymous once it is in a folder.
What does the strength control actually change?
Strength multiplies the measured slope before the vector is normalised, from 0.1 to 10, starting at 2. At a low strength the normals stay close to straight up and the surface catches light gently; at a high strength the same slopes tilt much further and the shading gets hard and faceted. It is not a detail control: it cannot add height the source does not contain, which is why a flat grey image comes back as the flat normal 128, 128, 255 at every strength the tool offers. Set it by eye against your own lighting, since the right value depends on how deep the surface is meant to look, not on the image.
Why is a normal map mostly the same blue-violet colour?
Because a tangent-space normal map stores a direction, not a colour, and most of a surface faces straight out of itself. The vector (0, 0, 1) encodes to red 128, green 128, blue 255, the blue-violet that covers the flat parts of every normal map you have seen. Red carries the left-to-right tilt, green the up-and-down tilt, and blue how directly the surface faces outwards; each byte is that component of a unit vector mapped from minus one through zero to plus one. Every pixel this tool writes decodes back to a vector of length one, to within the rounding a single byte per channel allows, which is what makes the result usable as geometry rather than as a picture of one.
What do the clamp and wrap edge modes do?
They decide what a 3 by 3 kernel reads when it hangs off the edge of the image, and the answer is never a guess. Clamp repeats the border pixel outward, so the edge measures about half the slope of the interior and no cliff is invented at the frame. Wrap reads the opposite edge instead, which is what a tiling texture needs: the slope across the seam is measured from the pixels that will actually meet there, so the repeat does not show a line. On an image that does not tile, wrap invents a slope at the border that is not in the source, so clamp is the safer default and it is what the tool starts with.
Is my image uploaded, and what do I get back?
Nothing is uploaded. The file is read by the page itself, decoded by your browser, converted in memory and written back out as a PNG named after your file; there is no server in this, no account, no watermark and nothing about the image is handed to analytics. Images up to 20 megapixels are accepted, which covers a 4,000 by 5,000 texture, and a larger one is refused in words with the size it read and the ceiling rather than being quietly shrunk. What comes out has the same pixel dimensions as what went in, is RGB with no transparency, and the only thing kept between visits is your strength, format and edge setting.

A Sobel gradient over the image's luminance, encoded as a tangent-space normal map. It derives slope from brightness, so it is only as good as the height data in the source; it is not a substitute for a sculpted map.