Light sources do not make textures brighter than texture source images

I’m using stock OpenGL with no shaders and several light sources. I’ve noticed that regardless of my light sources’ RGBA settings or number of lights the brightest a model will get is the actual image being used for the texture map. I can have the diffuse, ambient, etc. settings for a light source all set to something ridiculous like 1000 but a material with a dark texture map will still appear dark under extremely bright lighting, as if the lighting is being clamped or normalized. I’d expect them to become saturated or solid white with a high enough lighting intensity.

My lighting strategy is to have all the lights set to various intensities of white and control the color tinting of the material texture maps (generally being light-gray metallic textures) using Gl_Materialfv. The issue remains even when setting both the lighting and material parameters to large values.

Is this a limitation of OpenGL, or is there a proper way to use an arbitrary texture map, set its color tint with Gl_Materialfv, and have the light sources make it brighter than the texture map’s source image? Here’s the (hopefully) relevant source code:

http://eightvirtues.com/games/sylph/Dev/Sylph%20Lighting%20and%20Material%20Code

And yes, I’m Jon Snow and I know nothing. :slight_smile:

Anything which can be done with fixed-function lighting can also be done by setting each vertex’ colour explicitly (via e.g. glColor). And fixed-function colours can’t be brighter than white; you can specify values greater than 1.0, but they will be clamped prior to interpolation. With older (OpenGL 1.x) hardware, this is typically a hardware limitation (i.e. the hardware represents colours as normalised values where all-ones represents 1.0).

Exactly how the interpolated colour is combined with the colour from the texture map is determined by the glTexEnv(GL_TEXTURE_MODE) setting. This defaults to GL_MODULATE, which multiplies the texture colour by the interpolated colour, so the result will never be any brighter than the original texture colour (conversely, with GL_ADD the result will never be any darker than the original texture colour).

This can be done with shaders, although it’s unclear (to me) whether you need to provide both a vertex shader and a fragment shader, or just a vertex shader (i.e. whether the value assigned to gl_FrontColor is clamped by the implementation).

With GL 1.4 or the GL_ARB_texture_env_combine extension (there’s also an _EXT version but I’m ignoring that because _ARB is ubiquitous) you can set an RGB scaling factor of 1, 2 or 4 which is applied to the glTexEnv setting, and which can then be used to overbrighten the lighting result.

Thanks GClements and mhagain for your excellent replies. I think I’ve found a decent solution, though I’ve yet to rectify/disable it for my orthogonal passes (GUI/OSD/background stuff), which have lighting disabled. I’m now setting up my texture environment like this:

Gl.TexEnvi(Gl.TEXTURE_ENV, Gl.TEXTURE_ENV_MODE, Gl.COMBINE)
Gl.TexEnvi(Gl.TEXTURE_ENV, Gl.COMBINE_RGB_ARB, Gl.MODULATE)
Gl.TexEnvi(Gl.TEXTURE_ENV, Gl.RGB_SCALE_ARB, 2)

This appears to make everything twice as bright and allows oversaturation, which is ideal. The next trick then was to take all my light sources and cut their strengths in half. Now when the sum of all light sources exceeds 0.5 (during explosions, for example) the texture maps begin to exceed the RGB value of their bitmap, eventually oversaturating them to white. Here are a few cropped screenshots to demonstrate:

Previously the models would “max out” at the texture map’s source image, appearing uniformly lit as if fully ambient, which looked horrible. Anyway, someone should make this a sticky, as I couldn’t find anything online in the vein of “all OpenGL noobs should read this” and it seems pretty essential knowledge. Something else essential regarding similar effects is switching between these:

Gl.BlendFunc(Gl.SRC_ALPHA, Gl.ONE_MINUS_SRC_ALPHA)

Gl.BlendFunc(Gl.SRC_ALPHA, Gl.ONE)

The first renders geometry “normally”, while the second adds the geometry’s colors to whatever has already been rendered behind it. This is essential when rendering explosions using particles to give that supersaturated/HDR effect.

Thanks to both of you, who will be added to the game credits. Let me know if you just want me to use your opengl.org usernames or something different.