Light Attenuation

Point Light Distance Attenuation

This is the commonly used formula to attenuate light by a constant, linear and quadric factor.

1 / (constantFactor + (linearFactor * disFactor) + (quadricFactor * disFactor * disFactor));

personally I dislike this formula as it is very difficult to isolate light to a particular area only.

 Spherical Light Attenuation

This is something I use more frequently.

saturate(1.0 – smoothstep(lightAttMinRange, lightMaxRange, lightDis));

This will only start attenuate at a specific distance and will have a smooth fall off to the lightMaxRange. It really make lights placement in room simpler.

Spot Light Attenuation

float spot = dot(spotlightDir, lightDir);

float outerAngleFactor = cos(outerAngleFactor / 2);

float innerAngleFactor  = cos(innerAngleFactor / 2);

float attenuation = (spot >= outerAngleFactor) * pow((spot – outerAngleFactor) / (innerAngleFactor – outerAngleFactor), falloff);

if you are using ogre, outerAngleFactor and attenuation  is calculated for you. if you are using lightVec from NdotL, do remember to inverse the direction.

Create a simple mini-map using Ogre3D and CEGUI

Objective: Creating a mini-map display using Ogre 3D and CEGUI.

Difficulty: Beginner
Code Length: Short
 
This tutorial explains how to render the whole scene from a top down view and render it to a CEGUI StaticImage.
 
//calculate the height of camera to view the whole scene
 
Ogre::Radian fieldOfView = _camera->getFOVy();
float height = _sceneLength/2 / Ogre::Math::Sin(fieldOfView / 2);
 
Vector3 cameraPosition = Vector3(_sceneLength/2,_sceneWidth/2, height);
Vector3 lookAt = Vector3(_sceneLength/2,_sceneWidth/2, 0);
 
//create a texture for the mini-map to render on
 
TexturePtr texture = TextureManager::getSingleton().createManual(“mmTex”,
   ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
   512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
 
RenderTarget rt = texture->getBuffer()->getRenderTarget();
{
   //create a minimap camera, use the same settings as main camera
   _mmCamera = _sceneManager->createCamera(“minimapCamera”);
   _mmCamera->setNearClipDistance(_camera->getNearClipDistance());
   _mmCamera->setFarClipDistance(_camera->getFarClipDistance());
 
   //AspectRatio(1) is for a square minimap
   _mmCamera->setAspectRatio(1);
   _mmCamera->setPosition(cameraPosition);
   _mmCamera->lookAt(lookAt);
   Viewport *vp = _rt->addViewport(_mmCamera);
   vp->setClearEveryFrame(true);
   vp->setOverlaysEnabled(false);
   vp->setBackgroundColour(ColourValue::Black);
}
 
//Create a CEGUI texture from mmTex
CEGUI::Texture* cetex = GUIManager::instance()->_guiRenderer->createTexture((CEGUI::utf8*) “mmTex”);
 
//CEGUI require an imageset to store the texture
CEGUI::Imageset* imageset = CEGUI::ImagesetManager::getSingleton().createImageset((CEGUI::utf8*)”minimapTexImageset”, cetex);
 
imageset->defineImage((CEGUI::utf8*)”minimapImage”,
CEGUI::Point(0.0f, 0.0f),
CEGUI::Size(cetex->getWidth(), cetex->getHeight()),
CEGUI::Point(0.0f,0.0f));
 
//retrieve the CEGUI StaticImage(window) used to render the minimap
CEGUI::Window* si = CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)”MiniMap”);
si->setProperty(“Image”, CEGUI::PropertyHelper::imageToString(
   &imageset->getImage((CEGUI::utf8*)|CEGUI::utf8*)”minimapImage”)));