Light: Pseudo sort lights distance using bucket to evict them fast.

Lower max light level to 16 as it proves sufficient.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14801 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
vincentlj 2013-12-27 00:34:41 +00:00
parent 4d0b9236b2
commit 30a030bd4c
2 changed files with 26 additions and 32 deletions

View File

@ -1,8 +1,8 @@
uniform sampler2D ntex;
uniform vec4 center[32];
uniform vec4 col[32];
uniform float energy[32];
uniform vec4 center[16];
uniform vec4 col[16];
uniform float energy[16];
uniform int lightcount;
uniform float spec;
uniform vec2 screen;

View File

@ -666,7 +666,7 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat,
}
// ----------------------------------------------------------------------------
#define MAXLIGHT 16 // to be adjusted in pointlight.frag too
void IrrDriver::renderLights(const core::aabbox3df& cambox,
scene::ICameraSceneNode * const camnode,
video::SOverrideMaterial &overridemat,
@ -681,9 +681,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
m_video_driver->setRenderTarget(rtts, true, false,
video::SColor(0, 0, 0, 0));
const vector3df camcenter = cambox.getCenter();
const float camradius = cambox.getExtent().getLength() / 2;
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
PointLightProvider * const pcb = (PointLightProvider *) irr_driver->
getCallback(ES_POINTLIGHT);
@ -700,49 +697,46 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
const u32 lightcount = m_lights.size();
const core::vector3df &camdir = (camnode->getTarget() - camcenter).normalize();
float fov = camnode->getFOV() / 2.;
const core::vector3df &campos =
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
std::vector<float> accumulatedLightPos;
std::vector<float> accumulatedLightColor;
std::vector<float> accumulatedLightEnergy;
unsigned lightnum = 0;
std::vector<LightNode *> BucketedLN[15];
for (unsigned int i = 0; i < lightcount; i++)
{
if (!m_lights[i]->isPointLight()) {
m_lights[i]->render();
continue;
}
if (lightnum >= 32)
const core::vector3df &lightpos = (m_lights[i]->getPosition() - campos);
unsigned idx = lightpos.getLength() / 10;
if(idx > 14)
continue;
// Light culling
const core::vector3df &lightpos = (m_lights[i]->getPosition() - camcenter);
float light_radius = m_lights[i]->getRadius();
float dotprod = camdir.dotProduct(lightpos);
if (dotprod > 0.) {
// Pixels in front of camera
// Are they too far ?
if (lightpos.getLength() > camradius)
continue;
// Is it too divergent from camera normal ?
float othogonal_max_dst = light_radius + dotprod * tan(fov);
if (lightpos.getLengthSQ() - dotprod * dotprod > othogonal_max_dst * othogonal_max_dst)
continue;
} else if (lightpos.getLength() > light_radius)
continue;
const core::vector3df &pos = m_lights[i]->getPosition();
BucketedLN[idx].push_back(m_lights[i]);
}
unsigned lightnum = 0;
for (unsigned i = 0; i < 15; i++) {
for (unsigned j = 0; j < BucketedLN[i].size(); j++) {
if (++lightnum > MAXLIGHT)
break;
LightNode *LN = BucketedLN[i].at(j);
const core::vector3df &pos = LN->getPosition();
accumulatedLightPos.push_back(pos.X);
accumulatedLightPos.push_back(pos.Y);
accumulatedLightPos.push_back(pos.Z);
accumulatedLightPos.push_back(0.);
const core::vector3df &col = m_lights[i]->getColor();
const core::vector3df &col = LN->getColor();
accumulatedLightColor.push_back(col.X);
accumulatedLightColor.push_back(col.Y);
accumulatedLightColor.push_back(col.Z);
accumulatedLightColor.push_back(0.);
accumulatedLightEnergy.push_back(m_lights[i]->getEnergy());
lightnum++;
} // for i in lights
accumulatedLightEnergy.push_back(LN->getEnergy());
}
if (lightnum > MAXLIGHT)
break;
}
LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy);
// Handle SSAO
SMaterial m_material;