2D normal map generation

Started by
12 comments, last by Basic 18 years, 10 months ago
Hello, I was recently using Nvidia's normal map filter with Gimp 2(it's also availiable for Photoshop if you've got it), and I wanted to create my own normal map filter. By doing this, I'd be able to generate normal maps on the fly in my games, and help cut down on media a bit. Does anyone know where I could learn about generating a normal map from a regular rgb image? As far as I've researched, it's a matter of going from Initilial image --> Greyscale image --> normal map Generating the greyscale is no problem, I've made my own alogrithm for that, but I have no idea where to begin with generating a normal map. I'd really appreciate any help, thanks. 8)
I ask for help and you give me a book? I hate book. Book is stupid.Also known as Yellow at the Dark Basic forums.
Advertisement
Once you've got a greyscale image, just treat it like a height map and generate the normals for it. Once you've got the normals then these can be encoded into an RGB colour without too much work.
So it really doesn't matter if I get that fancy "blue shade" for my normal map to really work?

Right now I'm trying something like this

red = (pixelx + 255)/2
green = (pixely + 255)/2
blue = 255

I understand that the blue channel must always be there, is this correct?

[EDIT]
Never mind what I said above. :)
I'll post again shortly. I think I almost have it down.


[EDIT AGAIN]

So if I understand correctly, to generate a normal map, it's just the average color of the pixel from the left,right,top,and bottom, and the red and green channels are where the height is taken from?

:)
I ask for help and you give me a book? I hate book. Book is stupid.Also known as Yellow at the Dark Basic forums.
That blue shade comes from almost everyone using the blue channel for the local up (usually Z) axis. XYZ->RGB maps rather intuitivly. So for a mostly flat surface you end up with most normals pointing outwards, so they get almost full blue and greater or lesser amounts of red and green depending on the actual tilt.

You basically need to get the delta (change) in height between your current greyscale point and all the adjacent ones. From these you get your tangent vectors, then you do a cross product to get your final normal. And don't forget to rescale your normals' XYZ components from [-1, +1] to [0, 255].
Okay, thanks for the help. I have just successfully got an image generated. :)

I'm interested in knowing how to define the edges more, or add more depth to my normal map though. Any ideas on how this is done?
I ask for help and you give me a book? I hate book. Book is stupid.Also known as Yellow at the Dark Basic forums.
After some fiddling around a little bit I have got the normal map working perfectly. I can't alter it or do anything fancy, but it works. :) I know it works because I've tested with images I'd made in GIMP prior to this.

However, I'm having some problems creating a heightmap. I've generated a greyscale image, but that doesn't seem to be good enough. Anyone know where I could find an alogrithm for generating proper heightmaps?

Is my process wrong?

Should this

a.) Initial image --> Greyscale image --> normal map

by changed to this

b.) Initial image --> Greyscale image --> Heightmap --> normal map

or maybe this

c.) Initial image --> Heightmap --> normal map

Thanks for any help provided.

I ask for help and you give me a book? I hate book. Book is stupid.Also known as Yellow at the Dark Basic forums.
You can't just take a regular texture and generate a normal map from it, as the information just isn't there. Heightmaps are usually drawn by the artist at the same time as they create the texture.

Note also that RGB->greyscale usually involves different weightings for the different colours than just a straight avarage.
Yeah, right now I'm just using an average of the points. So are you saying I need to draw a new texture manually for the height map? Or are you saying that after the greyscale is generated, I need to play with the weights before generating the normal map?

Thanks for all your help.
I ask for help and you give me a book? I hate book. Book is stupid.Also known as Yellow at the Dark Basic forums.
Ack, I'm so close. I think I've got the heightmap down, and I think I know where the problem is.

I think the problem is with the scaling.

Could you elaborate or perhaps show me what you mean by this?

"And don't forget to rescale your normals' XYZ components from [-1, +1] to [0, 255]."


Thank you for all your help so far OrangyTang. + Points
I ask for help and you give me a book? I hate book. Book is stupid.Also known as Yellow at the Dark Basic forums.
For a proper look it'll have to be hand created. But if you're going with the automatic conversion you'll likely get better results with proper weights. There was an IOTD a while back where someone did Quake 2 with automatically generated normalmaps (like this) which looked pretty good. This tends to work with pre-bumpmapping textures because they're drawn with the more raised areas brighter.

For conversion, your image/texture will probably be a 32bit texture, which gives you 8bits per colour. So each colour is in the range 0 to 255. Normals are usually in the range of -1 to 1 for each X/Y/Z value, so you have to do a bit of scaling and shifting to get the correct float->byte conversion. Something like:

R = (byte)((X+1f) / 128f);

Actually, since the Z/B component is always +itive your bumpmapping could do something sneaky and assume it was orignally [0,1] and get more precion. But thats probably not going to give you much of a visual difference.

This topic is closed to new replies.

Advertisement