So you may ask : how ? Is there any trick needed ?
Yes, a "trick" is needed : crossbar. Cross-bar texture lookup allows to use a texel from another texture unit than the current texture unit.
Crossbar is available on cards that support ARB_texture_env_crossbar or NV_texture_env_combine4, that is the majority of ATi hardware (all Radeon) and nVidia hardware (all GeForce, all Quadro, all TNT).
Let's rewrite the texture environment functions you used with some other syntax :
reminder : it computes diffuse_intensity*decal*attn
TEXTURE UNIT 0 : REPLACE(TEXTURE) == L
TEXTURE UNIT 1 : DOT3(PREVIOUS,TEXTURE) == L dot N
TEXTURE UNIT 2 : MODULATE(TEXTURE,PREVIOUS) == decal*(L dot N)
TEXTURE UNIT 3 : MODULATE(TEXTURE,PREVIOUS) == attn*decal*(L dot N)
Now, to compute the new lighting equation that includes ambient, the goal is : ((diffuse_intensity*attn)+ambient)*decal
With texture environment crossbar it can be computed using the following configuration :
TEXTURE UNIT 0 : DOT3(TEXTURE,TEXTURE1) = L dot N
TEXTURE UNIT 1 : MODULATE(TEXTURE3,PREVIOUS) = attn*(L dot N)
TEXTURE UNIT 2 : ADD(CONSTANT,PREVIOUS) = ambient+attn*(L dot N)
TEXTURE UNIT 3 : MODULATE(TEXTURE2,PREVIOUS) = decal*(ambient+attn*(L dot N))
That works when attenuation is enabled, but since you have an option to disable attenuation, here's the setup for non-attenuated lighting with ambient. The goal is : (diffuse_intensity+ambient)*decal
TEXTURE UNIT 0 : DOT3(TEXTURE,TEXTURE1) = L dot N
TEXTURE UNIT 1 : ADD(CONSTANT,PREVIOUS) = ambient+(L dot N)
TEXTURE UNIT 2 : MODULATE(TEXTURE,PREVIOUS) = decal*(ambient+(L dot N))
Are you still ok ?
[Edited by - vincoof on June 26, 2004 9:45:20 PM]
Per pixel light attenuation and bump mapping
Now, on to the code :)
I'm just rewriting things based on your code.
Old code :
New code :
and please post screenshots when it's done ;)
I'm just rewriting things based on your code.
Old code :
glActiveTextureARB(GL_TEXTURE2_ARB);glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, m_textures[pFace->textureID]);if(g_Attenuation){GLfloat light_center[] = { LightPosition.x, LightPosition.y, LightPosition.z }; enableAttenuation3D(GL_TEXTURE3_ARB, tex3Dattn, light_radius, light_center);}//Bind normalisation cube map to texture unit 0glActiveTextureARB(GL_TEXTURE0_ARB);glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, m_normcubemap[pFace->textureID]);glEnable(GL_TEXTURE_CUBE_MAP);//Set up texture environment to do (tex0 dot tex1)*colorglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE) ;//Bind normal map to texture unit 1glActiveTextureARB(GL_TEXTURE1_ARB);glBindTexture(GL_TEXTURE_2D, m_normalmap[pFace->textureID]);glEnable(GL_TEXTURE_2D);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB_ARB) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE) ;
New code :
GLfloat ambient_color[4] = { Ambient.red, Ambient.green, Ambient.blue, 1.f };glActiveTextureARB(GL_TEXTURE2_ARB);glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, m_textures[pFace->textureID]);if(g_Attenuation){glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS) ;glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, ambient_color);}else{glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);}if(g_Attenuation){GLfloat light_center[] = { LightPosition.x, LightPosition.y, LightPosition.z }; enableAttenuation3D(GL_TEXTURE3_ARB, tex3Dattn, light_radius, light_center);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE2_ARB) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS) ;}//Bind normalisation cube map to texture unit 0glActiveTextureARB(GL_TEXTURE0_ARB);glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, m_normcubemap[pFace->textureID]);glEnable(GL_TEXTURE_CUBE_MAP);//Set up texture environment to do (tex0 dot tex1)*colorglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB_ARB) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1_ARB) ;//Bind normal map to texture unit 1glActiveTextureARB(GL_TEXTURE1_ARB);glBindTexture(GL_TEXTURE_2D, m_normalmap[pFace->textureID]);glEnable(GL_TEXTURE_2D);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);if(g_Attenuation){glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE3_ARB) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS) ;}else{glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT) ;glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS) ;glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, ambient_color);}
and please post screenshots when it's done ;)
after an entire night of constant attempts, i've made attenuation light work, see it here:
http://www.neoborn.com/users/b3rs3rk/attenuation.jpg
but i still cant combine ambient light with attenuation :/ what i have now is:
http://www.neoborn.com/users/b3rs3rk/amb_atten.jpg
i wanted something like this:
http://www.neoborn.com/users/b3rs3rk/ambient.jpg
(this is a screen made with the texture3d code with the broken ATI register combiners <--pratically useless, but gives the point :/)
http://www.neoborn.com/users/b3rs3rk/attenuation.jpg
but i still cant combine ambient light with attenuation :/ what i have now is:
http://www.neoborn.com/users/b3rs3rk/amb_atten.jpg
i wanted something like this:
http://www.neoborn.com/users/b3rs3rk/ambient.jpg
(this is a screen made with the texture3d code with the broken ATI register combiners <--pratically useless, but gives the point :/)
Quote: Original post by b3rs3rk
i wanted something like this:
http://www.neoborn.com/users/b3rs3rk/ambient.jpg
In fact, this is not the result you *should* have. This is not real ambient lighting.
Quote: Original post by b3rs3rk
after an entire night of constant attempts, i've made attenuation light work, see it here:
http://www.neoborn.com/users/b3rs3rk/attenuation.jpg
Is this what you get with the code I've posted above ? Or did you change the texenv calls a bit ?
It looks like the following is computed : (diffuse_intensit+ambient)*attn*decal
instead of : ((diffuse_intensity*attn)+ambient)*decal
Just a quick test : setup ambient_color to {0,0,0,0} --> it should give the same result as if ambient was disabled. If results are different, the's definately a problem in the texenv calls.
infact, i've changed the code a bit... i simply compute diffuse_intensit*attn*decal.
how can i obtain the other effect (the one i should not have) ?
how can i obtain the other effect (the one i should not have) ?
I'm not quite sure to understand. Why do you want to make the effect that "should" not be rendered ?
Anyway, this is done by : (diffuse_intensity*attn*decal)+ambient
But while it may look somehow good in your example, in most cases it will look crap. It tends to make scenes grey-ish (when using a grey ambient color, which is the case most of the time) and too bright.
Anyway, this is done by : (diffuse_intensity*attn*decal)+ambient
But while it may look somehow good in your example, in most cases it will look crap. It tends to make scenes grey-ish (when using a grey ambient color, which is the case most of the time) and too bright.
maybe the screenshot is not so accurate. pratically i want a simple coloured light,nothing more..
if i use the attenuation code u gave me(again, thanks!!), i have a (for example) red light but the rest of the room is black.
all i need is a simple way to render a pointlight and manage its brightness and its color, with and/or without attenuation :D
if i use the attenuation code u gave me(again, thanks!!), i have a (for example) red light but the rest of the room is black.
all i need is a simple way to render a pointlight and manage its brightness and its color, with and/or without attenuation :D
With brightness and color, you have to setup this :
(diffuse_contribution*attn*light_diffuse_color+ambient_color)*decal
And the brightness is ruled by "ambient_color" and the color of the light is ruled bu "light_diffuse_color".
This can be done using the following scheme :
TEXTURE UNIT 0 : DOT3(TEXTURE,TEXTURE1) with TEXTURE=L and TEXTURE1=N
TEXTURE UNIT 1 : MODULATE(CONSTANT,PREVIOUS) with CONSTANT=light_diffuse_color
TEXTURE UNIT 2 : MAD(TEXTURE3,PREVIOUS,CONSTANT) with TEXTURE3=attn and CONSTANT=ambient_color
TEXTURE UNIT 3 : MODULATE(TEXTURE2,PREVIOUS) with TEXTURE2=decal
The only trick now is to setup the MAD function (MAD stands for "Multiply and ADd"). In fact : MAD(x,y,z) = x*y+z
(The MAD function is very popular in vertex and fragment programs).
This MAD operation can either be computed using the ATI_texture_env_combine3 extension or using the NV_texure_env_combine4 extension.
I won't write down the code for setting up glTexEnv calls, because I think you can do it yourself :)
And if you doubt about your code, feel free to post it when it's done so that we can validate it.
(diffuse_contribution*attn*light_diffuse_color+ambient_color)*decal
And the brightness is ruled by "ambient_color" and the color of the light is ruled bu "light_diffuse_color".
This can be done using the following scheme :
TEXTURE UNIT 0 : DOT3(TEXTURE,TEXTURE1) with TEXTURE=L and TEXTURE1=N
TEXTURE UNIT 1 : MODULATE(CONSTANT,PREVIOUS) with CONSTANT=light_diffuse_color
TEXTURE UNIT 2 : MAD(TEXTURE3,PREVIOUS,CONSTANT) with TEXTURE3=attn and CONSTANT=ambient_color
TEXTURE UNIT 3 : MODULATE(TEXTURE2,PREVIOUS) with TEXTURE2=decal
The only trick now is to setup the MAD function (MAD stands for "Multiply and ADd"). In fact : MAD(x,y,z) = x*y+z
(The MAD function is very popular in vertex and fragment programs).
This MAD operation can either be computed using the ATI_texture_env_combine3 extension or using the NV_texure_env_combine4 extension.
I won't write down the code for setting up glTexEnv calls, because I think you can do it yourself :)
And if you doubt about your code, feel free to post it when it's done so that we can validate it.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement