Dynamic lighting from projectiles
by Chris Byars · in Torque Game Engine Advanced · 04/13/2007 (6:58 pm) · 13 replies
Setting projectile datablock to have hasLight = true and its light colors/etc defined, the terrain is lit as such:

Is it supposed to look like that? Shouldn't it be a smooth edge, and not have the same lighting over a terrain square until it moves over the next terrain square?

Is it supposed to look like that? Shouldn't it be a smooth edge, and not have the same lighting over a terrain square until it moves over the next terrain square?
About the author
#2
04/16/2007 (4:02 pm)
I have to echo that I've been seeing this lighting artifact on legacy terrain while porting AFX to TGEA. In comparing very similar lighting circumstances on identical terrain between engines I see this very clearly on TGEA where I don't see it in TGE. I have not as yet been able to delve deeper into the reason.
#3
04/16/2007 (4:10 pm)
Glad to know I'm not alone on this at least. :)
#4
Btw: are there any light setting that this is more noticeable on, or does it always happen?
04/17/2007 (3:56 pm)
Hmm, I'll take a look at this - thanks for pointing out.Btw: are there any light setting that this is more noticeable on, or does it always happen?
#5
I'm seeing this artifact on just about any light with a radius large enough to reach the nearest legacy terrain seam. This includes sgLightObject lights as well as lower level LightInfo type lights that Projectile creates. Visually, it's as if sections of terrain are selected for lighting using a smaller radius than whatever radius describes the actually visible limits of the light's effect.
04/20/2007 (11:41 am)
I finally found some time to experiment with this a little more...I'm seeing this artifact on just about any light with a radius large enough to reach the nearest legacy terrain seam. This includes sgLightObject lights as well as lower level LightInfo type lights that Projectile creates. Visually, it's as if sections of terrain are selected for lighting using a smaller radius than whatever radius describes the actually visible limits of the light's effect.
#6
04/28/2007 (5:27 pm)
Wow, that is not smooth at all, that light effect needs to be redone in a sence of not looking so much like a square exactly... wow this whole picture really upsets me. if a fix is made or possible, please let us know lol.
#7
04/29/2007 (4:52 am)
The light is smooth ... problem seems more to be correct "multi atlas2 chunk" lighting ... similar effects can happen to shadows if you do not raise the radius in the shadow caster setup datablock.
#8
I had some time to look into this. Some lighting models falloff over very long distances and are cutoff by the dynamic light map texture edges, and the clamp mode used to render the texture is repeating its edge lexels.
Here's a replacement for sgLightingModel::sgGenerateDynamicLightingTexture (located in sgLightingModel.cc) that prevents the repeating and minimizes harsh edges in the dynamic light map:
05/17/2007 (11:26 am)
Hey guys,I had some time to look into this. Some lighting models falloff over very long distances and are cutoff by the dynamic light map texture edges, and the clamp mode used to render the texture is repeating its edge lexels.
Here's a replacement for sgLightingModel::sgGenerateDynamicLightingTexture (located in sgLightingModel.cc) that prevents the repeating and minimizes harsh edges in the dynamic light map:
void sgLightingModel::sgGenerateDynamicLightingTexture()
{
LightInfo *oldlight = sgLight;
// setup basic light...
LightInfo light;
light.mType = LightInfo::Point;
light.mRadius = 10.0;
light.mColor = ColorF(1.0, 1.0, 1.0);
light.sgLocalAmbientAmount = 1.0;
light.sgDoubleSidedAmbient = true;
light.sgUseNormals = false;
// set state...
sgResetState();
sgSetState(&light);
sgInitStateLM();
// get the basics...
F32 dist = sgGetMaxRadius(true);
F32 maxlensq = (SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE - 1) * (SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE - 1);
Point3F halfamount(SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE,
SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE, SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE);
Point3F invhalfamount(1 / SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE,
1 / SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE, 1 / SG_DYNAMIC_LIGHTING_TEXTURE_HALFSIZE);
Point3F radiusdist(dist, dist, dist);
// misc...
ColorF diff, attn;
Point3F norm;
// fill out the omni...
U8 bits[SG_DYNAMIC_LIGHTING_TEXTURE_SIZE][SG_DYNAMIC_LIGHTING_TEXTURE_SIZE][SG_DYNAMIC_LIGHTING_TEXTURE_SIZE];
for(U32 x=0; x<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; x++)
{
for(U32 y=0; y<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; y++)
{
for(U32 z=0; z<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; z++)
{
Point3F pos(x, y, z);
pos += Point3F(0.5f, 0.5f, 0.5f);
pos -= halfamount;
if(pos.lenSquared() >= maxlensq)
{
bits[x][y][z] = 0;
continue;
}
pos *= invhalfamount;
pos *= radiusdist;
diff = attn = ColorF(0.0f, 0.0f, 0.0f);
norm = VectorF(0.0f, 0.0f, 0.0f);
sgLightingLM(pos, SG_STATIC_SPOT_VECTOR_NORMALIZED, diff, attn, norm);
bits[x][y][z] = mClamp(S32(attn.red * 255.f), S32(0), S32(255));
}
}
}
// upload...
sgDynamicLightingTextureOmni = GFX->mTextureManager->createTexture(SG_DYNAMIC_LIGHTING_TEXTURE_SIZE,
SG_DYNAMIC_LIGHTING_TEXTURE_SIZE, SG_DYNAMIC_LIGHTING_TEXTURE_SIZE,
bits, GFXFormatL8, &GFXDefaultStaticDiffuseProfile);
// change to spot...
light.mDirection = VectorF(-1.0, 0.0, 0.0);
light.mType = LightInfo::SGStaticSpot;
light.sgSpotAngle = 90;
// set lighting model to spot...
sgResetState();
sgSetState(&light);
sgInitStateLM();
// fill out the spot...
for(U32 x=0; x<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; x++)
{
for(U32 y=0; y<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; y++)
{
for(U32 z=0; z<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; z++)
{
Point3F pos(x, y, z);
pos += Point3F(0.5f, 0.5f, 0.5f);
pos -= halfamount;
if(pos.lenSquared() >= maxlensq)
{
bits[x][y][z] = 0;
continue;
}
pos *= invhalfamount;
pos *= radiusdist;
diff = attn = ColorF(0.0f, 0.0f, 0.0f);
norm = VectorF(0.0f, 0.0f, 0.0f);
sgLightingLM(pos, SG_STATIC_SPOT_VECTOR_NORMALIZED, diff, attn, norm);
bits[x][y][z] = mClamp(S32(attn.red * 255.f), S32(0), S32(255));
}
}
}
// upload...
sgDynamicLightingTextureSpot = GFX->mTextureManager->createTexture(SG_DYNAMIC_LIGHTING_TEXTURE_SIZE,
SG_DYNAMIC_LIGHTING_TEXTURE_SIZE, SG_DYNAMIC_LIGHTING_TEXTURE_SIZE,
bits, GFXFormatL8, &GFXDefaultStaticDiffuseProfile);
#ifdef SG_TEST_LIGHTING_TEXTURE
for(U32 x=0; x<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; x++)
{
for(U32 y=0; y<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; y++)
{
for(U32 z=0; z<SG_DYNAMIC_LIGHTING_TEXTURE_SIZE; z++)
{
bits[x][y][z] = 255;
}
}
}
sgTestLightingTexture = GFX->mTextureManager->createTexture(SG_DYNAMIC_LIGHTING_TEXTURE_SIZE,
SG_DYNAMIC_LIGHTING_TEXTURE_SIZE, SG_DYNAMIC_LIGHTING_TEXTURE_SIZE,
bits, GFXFormatL8, &GFXDefaultStaticDiffuseProfile);
sgDynamicLightingTextureOmni = sgTestLightingTexture;
sgDynamicLightingTextureSpot = sgTestLightingTexture;
#endif
// back to the original state...
sgResetState();
sgSetState(oldlight);
}
#9
05/22/2007 (6:53 am)
Thanks for the fix, it works great! :)
#10
05/28/2007 (12:02 pm)
This should be TGEA standar...
#11
05/28/2007 (9:58 pm)
I'm sure John will make sure it gets in the next release.
#12
06/26/2007 (2:57 pm)
I've been exercising this fix a bit and while I do observe a great improvement, it does produce a rather unnatural, blocky, octagonal lighting shape in some cases, (see pic). So, I was wondering if this fix is intended as an interim solution or a permanent one?
#13
10/12/2009 (12:04 am)
I've been having this difficulty in TGE 1.5 with terrains ported up from earlier versions, but I can't figure out where the corresponding terrain lighting function for 1.5 is.
Torque 3D Owner Will Smith