Dark Bit Factory & Gravity

PROGRAMMING => General coding questions => Topic started by: mind on January 05, 2007

Title: normal maps?
Post by: mind on January 05, 2007
anyone know of any good techniques to generate normal maps from textures, besides the standard x/y sobel that ATI use in their normal map generator?
Title: Re: normal maps?
Post by: Jim on January 05, 2007
I've tried this with some success:

Convert texture to greyscale.
For each pixel create 8 normals by looking at the change in gradient for each neighbouring pixel.
Average the 8 normals.

Jim
Title: Re: normal maps?
Post by: mind on January 05, 2007
I've tried this with some success:

Convert texture to greyscale.
For each pixel create 8 normals by looking at the change in gradient for each neighbouring pixel.
Average the 8 normals.

Jim

thanks for the quick reply :)

got a screenshot? i'd like to see it before i implement it.. and since i have NO experience whatsoever with generating bump/diffuse/normal maps, or with vectors/gradients/crossproducts etc(or maybe i do, i just dont know it lol.. thats what i get for beeing a graphician instead of a coder :P, no clue about terminology), some pseudo or example code would be really helpful..

im in the process of porting the source provided with ATI's tool, but it looks a bit clumsy imo, so i'd like to do it in a somewhat more elegant way if possible.
Title: Re: normal maps?
Post by: Jim on January 06, 2007
No screenshot, sorry, this is something I tried years ago.

The normal is the direction a surface is facing.  Imagine each of the greyscale colours is a point on a height map.  Then because a white is higher than a neighbouring grey, the normal won't point straight up out of the ground, it'll be sloped towards the grey one.
So you can generate some crude looking normals and add them all together.  The 8 normals look like
Code: [Select]
R2 = sqrt(2)/2

These are the 8 normals, they have coordinates
\|/
-+-
/|\

 R2,y0,-R2
  0,y1, -1
-R2,y2,-R2
  1,y3,  0
 -1,y4,  0
 R2,y5, R2
  0,y6,  1
-R2,y7, R2

And all those y coordinates are calculated like

di = i0 - in

where i0 is the intensity of the centre pixel and in is the intensity of the neighbour
Then

yn = sqrt(1 - di^2)

Add all 8 normals together and then re-normalise the result, ie.

length = sqrt(nx^2+ny^2+nz^2)
nx = nx/length
ny = ny/length
nz = nz/length

That gives you the normal at the given pixel.


Jim
Title: Re: normal maps?
Post by: mind on January 06, 2007
oh i see.. that made sense.. i got the ATI version working last night, but i'll make sure to try your method aswell.. thanks again, karma++
Title: Re: normal maps?
Post by: mind on January 06, 2007
ahh finally.. my tool is finished.. you can find a screenshot and executable overe here http://dbfinteractive.com/index.php?topic=1138.0 if you are interested in checking it out :)

thanks Jim, for somewhat pointing me in the right direction as far as normals, vectors and gradients go :) in the end though i opted to go for the implementation ATI use, both for DOT3 and DUDV, since it was easier to port it, than write and debug new shit.. lol..
Title: Re: normal maps?
Post by: Jim on January 07, 2007
The code you posted looks like it does something very similar, at first glance :)


edit> At second glance, it's completely different.  I'd really like to see a comparison.  If I write some (is it C) code to do it, would that help?  Write me a function prototype and I'll fill in the blanks.

Jim
Title: Re: normal maps?
Post by: mind on January 08, 2007
The code you posted looks like it does something very similar, at first glance :)


edit> At second glance, it's completely different.  I'd really like to see a comparison.  If I write some (is it C) code to do it, would that help?  Write me a function prototype and I'll fill in the blanks.

Jim

feel free to write one in C and i'll port it to delphi and run it on a few textures to compare the result. i can read C pretty well, i just cant write it.. lol..