Lighting
Purpose:
By default, the engine just gives a generic ambient lighting to any DTS object that is sitting on an interior. What we're going to do is check if the object can see the sun and if it can, light it accordingly. We will do this by casting a ray from the object we are trying to light towards the sun and see if we hit anything. If we dont hit anything, we must be standing in the sunlight.
Code:
New or modified code is shown in bold.
"..." Indicates that code has been omitted to save space.
In the file /sim/sceneObject.cc modify the function void SceneObject::installLights() to look something like this:
void SceneObject::installLights()
{
// install the lights:
LightManager * lightManager = gClientSceneGraph->getLightManager();
AssertFatal(lightManager!=NULL, "SceneObject::installLights: LightManager not found");
ColorF ambientColor;
if(getLightingAmbientColor(&ambientColor))
{
switch(mLightingInfo.mLightSource)
{
case LightingInfo::Interior:
{
const F32 directionalFactor = 0.4f;
const F32 ambientFactor = 0.6f;
LightInfo & light = mLightingInfo.smAmbientLight;
LightInfo & rLight = mLightingInfo.smReflectedLight;
light.mType = LightInfo::Ambient;
RayInfo info;
U32 mask = InteriorObjectType;
Point3F startPos, endPos;
getRenderWorldBox().getCenter(&startPos);
endPos = startPos + (DaylightCycle::getSunVector() * -50);
if(!gClientContainer.castRay(startPos, endPos, mask, &info))
{
light.mDirection = DaylightCycle::getSunVector();
light.mColor = DaylightCycle::getCurrentColor() * directionalFactor;
rLight.mDirection = VectorF(0.0, 0.0, -1.0);
rLight.mColor = ColorF(0.0, 0.0, -1.0) * directionalFactor;
}
else
{
light.mDirection = VectorF(0.57735f, 0.57735f, -0.57735f);
light.mColor = ambientColor * directionalFactor;
}
light.mAmbient = ambientColor * ambientFactor;
lightManager->addLight(&mLightingInfo.smAmbientLight);
lightManager->setVectorLightsEnabled(false);
break;
}
case LightingInfo::Terrain:
{
F32 factor = mClampF((ambientColor.red + ambientColor.green + ambientColor.blue) / 3.f, 0.f, 1.f);
lightManager->setVectorLightsAttenuation(factor);
break;
}
}
}
lightManager->installGLLights(getRenderWorldBox());
}
Caveats:
I didnt notice much of a performance drop when using this code but performing a ray cast every frame for every object may be too much in some cases. If it is, you could easily set up some code to do it every other frame or every 10 frames.
|