Strange specular phenomenon

Hi,

I have done a per-pixel lighting demo with diffuse and specular lighting. I use two cubemaps for normalization and vertex programming for calculation.

The diffuse light looks ok, but the specular looks strange. The hightlight is located at the right place but it looks like the filter is GL_NEAREST or something. The light is not interpolating over the surfuce but looks like circles, with different light brightness. It looks like alot of different sized circles with different lights on eachther.

Anyone know what the problem is?

//Regards, Ninja

sounds like a precision problem. are you multiplying the specular result by itself many times to get a higher exponent?
if so then the banding is because of only 8bit precision. think about what happens to your 8bit N.H result as you multiply it by itself several times and each time force the result to fit into 8 bits.

i have had better results by doing a dependent texture read based on N.H to get the specular result - you can make different textures for each specular exponent, or do the lookup based on N.H for one axis, and exponent on the other. in either case the texture is filtered between values and doesn’t look so banded.

it may also be that your normalmap textures are not high enough precision - if you use an nVIDIA card you could try the HILO format which is 16bit precision - you only need to store two values and it works out the z as sqrt(1 - x^2 - y^2). it will give you a greater range of N.H results.

[This message has been edited by vshader (edited 09-25-2002).]

Ok thanks, but can you explain this abit more

i have had better results by doing a dependent texture read based on N.H to get the specular result - you can make different textures for each specular exponent, or do the lookup based on N.H for one axis, and exponent on the other. in either case the texture is filtered between values and doesn’t look so banded.

What is a dependent texture read for example?

//Regards, Ninja

look into GL_NV_TEXTURE_SHADER or GL_ATI_FRAGMENT_SHADER.

a dependent texture read is where the texture coordinates for one texture look up depend on the texture colors (the result) from a previous texture lookup.

so what i was describing was - first get your N (normal) from a normal map, second get your H (half angle) as texture coords from vertex program, then use the N.H result as the texture coordinate to look up a 1D texture. you can do that with GL_DOT_PRODUCT_TEXTURE_1D_NV in nVidias tetxure shader 3 ext (gf4 only), or on the second pass thru an ATI fragment shader. it works better in ATIs version cos you can normalize H before doing the dependent N.H read.

or, you could do two dot products (say N.H and N.L) and use them as S & T texture coordinates for a 2D texture that has diffuse on one axis and specular on another.
that will work on gf3 too, as it only has texture shader and texture shader2, which have GL_DOT_PRODUCT_TEXTURE_2D_NV but not 1D. but again on the geforce you have denormalization problems…

there’s plenty of info on nVidia’s and ATI’s developer sites about techniques like these.
the ATI fragment shader extension is MUCH more flexible for dependent texturing (its very cool), but if you want to release your program more people have geforces, so… perhaps your best geforce bet is to try the HILO format normal maps.

edit: oops! i made NV_texture_shader sound better than it really is…

[This message has been edited by vshader (edited 09-25-2002).]