Scaling a mesh brightens light

I am writing a map editor that uses referenced staticmeshes, like the Unreal does. The meshes can be scaled, positioned, and rotated to fit in different places in the map.

I noticed that when I scaled a mesh down, the lighting gets brighter:

I am using a simple lighting envorinment with 2 lights, after the camera rotation is added to the matrix, and before any other matrix changes occur. Why would this be happening? How can I prevent it?

Here is my lighting setup:

Function EnableSimpleLighting()
glEnable GL_LIGHTING

glEnable GL_LIGHT0
bank=CreateBank(16)
PokeFloat bank,0,0.5
PokeFloat bank,4,0.5
PokeFloat bank,8,0.5
PokeFloat bank,12,1.0
glLightfv GL_LIGHT0,GL_DIFFUSE,bank
PokeFloat bank,0,WORLDSIZE*1.0
PokeFloat bank,4,WORLDSIZE*1.2
PokeFloat bank,8,-WORLDSIZE*1.4
PokeFloat bank,12,1.0
glLightfv GL_LIGHT0,GL_POSITION,bank
PokeFloat bank,0,0.0
PokeFloat bank,4,0.0
PokeFloat bank,8,0.0
PokeFloat bank,12,1.0
glLightfv GL_LIGHT0,GL_AMBIENT,bank
FreeBank bank

glEnable GL_LIGHT1
bank=CreateBank(16)
PokeFloat bank,0,0.25
PokeFloat bank,4,0.25
PokeFloat bank,8,0.25
PokeFloat bank,12,1.0
glLightfv GL_LIGHT1,GL_DIFFUSE,bank
PokeFloat bank,0,-WORLDSIZE*1.0
PokeFloat bank,4,-WORLDSIZE*1.2
PokeFloat bank,8,WORLDSIZE*1.4
PokeFloat bank,12,1.0
glLightfv GL_LIGHT1,GL_POSITION,bank
PokeFloat bank,0,0.0
PokeFloat bank,4,0.0
PokeFloat bank,8,0.0
PokeFloat bank,12,1.0
glLightfv GL_LIGHT1,GL_AMBIENT,bank
FreeBank bank
End Function

I can only guess from looking at this one function, but is the scaling related at all to the WORLDSIZE variable? If that were the case, then when you made the cube smaller, the light would also be drawn closer, making the object appear brighter.

Have you tried glEnable(GL_NORMALIZE)? …although, I thought scaling the model down would make the light darker, but maybe I have it backwards.

I considered that the normals might be getting scaled…but assumed that OpenGL would take that into account when calculating light intensity. I mean, isn’t it designed so that you can scale meshes any way you like and still get the same lighting?

Points of interest:
-The light in the shots above is a point light with no attenuation (default setting). No attenutation means light distance is irrelevant, right?

-I changed the lighting to use directional lights (see the recent directional lights thread I posted). Directional lighting means scale/distance are irrelevant, yet the effects remains. Shrinking the mesh increases brightness. Enlargening the mesh makes it darker.

Originally posted by halo:
I considered that the normals might be getting scaled…but assumed that OpenGL would take that into account when calculating light intensity. I mean, isn’t it designed so that you can scale meshes any way you like and still get the same lighting?
use glEnable(GL_NORMALIZE); but as it comes with a (very small nowadays) performance cost, it is not on by default.
Read the official technical FAQ, very good one (even if a bit outdated regarding performance tips) :
http://opengl.org/resources/faq/technical/lights.htm#ligh0090

I then tried enabling GL_NORMALIZE. This corrected the effect.

I have always avoided using this, because I assume that calculating a square root for each vertex will be significantly demanding. Is there a way to scale the normals, so that the card doesn’t have to make all these wasteful calculations?

Ok, but what are you doing to scale your models ? A normal should always have a magnitude of 1, even if you scale your model at any size. So, always ensure you normalize your normals.

Hope that helps.

Normals are always normalized. Otherwise this effect would be uniform, regardless of scale. Now when a mesh is scale 2x or 0.5x, I use the same normals arrays, which are normalized in local space, and always sum to 1.0.

Some transformations require changes to the magnitude of normal components, for example rotations, shear operations and in your case asymmetric scaling. OpenGL must be both efficient and consistent, it cannot do one thing with one matrix and something else with another.

You intuitively “know” what you want but expressing this as a mathematical quirk in matrix transformations of normals would be insane.

The good news is that OpenGL 1.2 and above does offer a mechanism for this, you can rescale normals without the need for a square root full normalize per normal.

Try:

glEnable(GL_RESCALE_NORMAL);

Obviously this will only work for uniform scaling operations, but it is ideal for your purpose.

By uniform, you mean x, y, and z have the same scale? Because I actually want to have arbitrary scaling, so meshes can be made to fit into the map where needed.

instead of normalizing the normals you could change the light intensity according to the scale factor.