Lights: Improve culling system

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14799 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
vincentlj 2013-12-26 20:14:49 +00:00
parent 46cce1e347
commit 508d866a2b
3 changed files with 23 additions and 10 deletions

View File

@ -47,6 +47,7 @@ public:
virtual u32 getMaterialCount() const OVERRIDE { return 1; }
virtual video::SMaterial& getMaterial(u32 i) OVERRIDE { return mat; }
virtual bool isCullable() { return true; }
float getRadius() const { return m_radius; }
void getColor(float out[3]) const { memcpy(out, m_color, 3 * sizeof(float)); }

View File

@ -683,8 +683,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
const vector3df camcenter = cambox.getCenter();
const float camradius = cambox.getExtent().getLength() / 2;
const vector3df campos = camnode->getPosition();
const float camnear = camnode->getNearValue();
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
PointLightProvider * const pcb = (PointLightProvider *) irr_driver->
@ -702,17 +700,30 @@ 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.;
for (unsigned int i = 0; i < lightcount; i++)
{
// Sphere culling
const float distance_sq = (m_lights[i]->getPosition() - camcenter).getLengthSQ();
float radius_sum = camradius + m_lights[i]->getRadius();
radius_sum *= radius_sum;
if (radius_sum < distance_sq)
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 (m_lights[i]->isCullable()) {
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;
}
m_lights[i]->render();
} // for i in lights
// Handle SSAO
SMaterial m_material;
GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver->
@ -845,4 +856,4 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
glDisable(GL_STENCIL_TEST);
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
}
}

View File

@ -32,6 +32,7 @@ public:
virtual ~SunNode();
virtual void render() OVERRIDE;
virtual bool isCullable() { return false; }
private:
ScreenQuad *sq;