singlepass lighting/reg combiners question

i’ve already posted this in the beginner section but with no luck…

I’ve been working from a demo that does perpixel lighting in one pass and i’ve gotten it working but now i’m trying to add a constant
ambient color to the equation…i might as well just throw the code up and see if someone can help

                         (i have gloss stored in diffuse's alpha)

                         code:
                         ------------------------------------------
                         glEnable(GL_TEXTURE_2D);
                         glBindTexture(GL_TEXTURE_2D, bump);

                         //Unit 1 - normalisation cube map
                         glActiveTextureARB(GL_TEXTURE1_ARB);
                         glEnable(GL_TEXTURE_CUBE_MAP_ARB);
                         glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normalize_cubemap_id);

                         //Unit 2 - normalisation cube map
                         glActiveTextureARB(GL_TEXTURE2_ARB);
                         glEnable(GL_TEXTURE_CUBE_MAP_ARB);
                         glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normalize_cubemap_id);

                         //Unit 3 - decal texture
                         glActiveTextureARB(GL_TEXTURE3_ARB);
                         glEnable(GL_TEXTURE_2D);
                         glBindTexture(GL_TEXTURE_2D, decal);

                         glActiveTextureARB(GL_TEXTURE0_ARB);

                         //Set up Register combiners
                         //3 general combiners
                         glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 4);

                         glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, gdlAmbient);

                         //combiner 0 does tex0.rgb dot tex1.rgb -> spare0.rgb,
                         /tex0.rgb dot tex2.rgb -> spare1.rgb
                         glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB,
                         GL_EXPAND_NORMAL_NV, GL_RGB);
                         glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE1_ARB,
                         GL_EXPAND_NORMAL_NV, GL_RGB);

                         glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE0_ARB,
                         GL_EXPAND_NORMAL_NV, GL_RGB);
                         glCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_TEXTURE2_ARB,
                         GL_EXPAND_NORMAL_NV, GL_RGB);

                         glCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_SPARE1_NV, GL_DISCARD_NV,
                         GL_NONE, GL_NONE, GL_TRUE, GL_TRUE, GL_FALSE);


                         //combiner 1 does spare1.rgb * spare1.rgb -> spare1.rgb
                         //spare0.rgb * tex3.rgb -> spare0.rgb

                         glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);
                         glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_SPARE1_NV,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);


                         glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_C_NV, GL_SPARE0_NV,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);
                         glCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_D_NV, GL_TEXTURE3_ARB,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);

                         glCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, GL_SPARE1_NV, GL_SPARE0_NV, GL_DISCARD_NV,
                         GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);


                         //combiner 2 does spare1.rgb * spare1.rgb -> spare1.rgb
                         glCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);
                         glCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV, GL_SPARE1_NV,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);


                         glCombinerOutputNV( GL_COMBINER2_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV,
                         GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);

                         //combiner 3 does spare1.rgb * spare1.rgb -> spare1.rgb
                         glCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);

                         glCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV, GL_SPARE1_NV,
                         GL_UNSIGNED_IDENTITY_NV, GL_RGB);

                         glCombinerOutputNV( GL_COMBINER3_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV,
                         GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);


                         //final combiner outputs spare1.rgb*spare1.rgb*tex0.a+spare0.rgb
                         //First do spare1.rgb*spare1.rgb in EF multiplier
                         glFinalCombinerInputNV(GL_VARIABLE_E_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
                         glFinalCombinerInputNV(GL_VARIABLE_F_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);

                         //Now do rest

                         glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_E_TIMES_F_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
                         glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); 
                         glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
                         glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);


                         glEnable(GL_REGISTER_COMBINERS_NV);

I recognise that code…
Sorry I didn’t reply to your email yet (I assume it was you).

Assuming your ambient brightness is stored in constant color 0, you need to add
const0.rgb*tex3.rgb to the final equation. Your best bet to do this is to use another general combiner to do:

spare0.rgb=spare0.rgb+tex3.rgb*const0.rgb

[This message has been edited by bakery2k (edited 02-16-2003).]

yea it was me… i see the cleverness of the bakery2k nick now too =]

thanks for the reply, and i just tried out your suggestion… i’m still learning to use the reg combiners and i’d really appreciate it if you could look over this bit of code i just did for the ambient…

the code from my first post is unchanged but this fourth combiner is added… does it look right to you? thanks again!

//combiner 4, spare0.rgb=spare0.rgb+tex3.rgb*const0.rgb

glCombinerInputNV(	GL_COMBINER4_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE0_NV,
					GL_UNSIGNED_IDENTITY_NV, GL_RGB);

glCombinerInputNV(	GL_COMBINER4_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ONE,
					GL_UNSIGNED_IDENTITY_NV, GL_RGB);

glCombinerInputNV(	GL_COMBINER4_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE3_ARB,
					GL_UNSIGNED_IDENTITY_NV, GL_RGB);

glCombinerInputNV(GL_COMBINER4_NV, GL_RGB, GL_VARIABLE_D_NV,
                  GL_CONSTANT_COLOR0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB); 


glCombinerOutputNV(	GL_COMBINER4_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV,
					GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);

this doesnt seem very logicak ie binding the same texture to 2 different textures units

//Unit 1 - normalisation cube map
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normalize_cubemap_id);

//Unit 2 - normalisation cube map
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normalize_cubemap_id);

to Bucky:
could you please send me your code to view it
on this email:rgrigoriev@yandex.ru.
I’ve got some troubles with per-pixel lighting on linux.
so why do you use 2 cubemaps?
Thanx in advance
Bye

Remember that COMBINER4 is actually the fifth combiner, so you need to change NUM_GENERAL_COMBINERS to 5. Also in this line:

glCombinerInputNV( GL_COMBINER4_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ONE,
GL_UNSIGNED_IDENTITY_NV, GL_RGB);

I don’t think GL_ONE is an acceptable input. Use GL_ZERO with a mapping of UNSIGNED_INVERT instead.

The reason there are 2 normalisation cube maps is that 1 is used for the light vector (for diffuse) and one is used for the half vector for specular.

About the normalization cube-map… Is it really necessary to use a cube-map? It seems like a waste of texture memory.

Is there some reason more people don’t use spherical coordinates instead of vectors? This way you can set the texture coordinates to the angles and have only one regular 2D texture to convert to a normalized color-encoded vector.

Originally posted by dismal:
[b]About the normalization cube-map… Is it really necessary to use a cube-map? It seems like a waste of texture memory.

Is there some reason more people don’t use spherical coordinates instead of vectors? This way you can set the texture coordinates to the angles and have only one regular 2D texture to convert to a normalized color-encoded vector.[/b]

as far as i know the spherical coordinates cannot be linearly interpolated…

yes it is a waste. just get a real gpu, then you can really normalize it
DP3 n.w,n,n;
RSQ n.w,n.w;
MUL n,n,n.w;

as far as i know the spherical coordinates cannot be linearly interpolated…

Hm, yes that is a pretty good reason I think if the normals aren’t too far apart this is a pretty good approximation though. But only use it if you absolutely have to…

Of course you’re right, this kind of discussion is pretty useless with modern hardware.