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:
parent
4d0b9236b2
commit
30a030bd4c
@ -1,8 +1,8 @@
|
|||||||
uniform sampler2D ntex;
|
uniform sampler2D ntex;
|
||||||
|
|
||||||
uniform vec4 center[32];
|
uniform vec4 center[16];
|
||||||
uniform vec4 col[32];
|
uniform vec4 col[16];
|
||||||
uniform float energy[32];
|
uniform float energy[16];
|
||||||
uniform int lightcount;
|
uniform int lightcount;
|
||||||
uniform float spec;
|
uniform float spec;
|
||||||
uniform vec2 screen;
|
uniform vec2 screen;
|
||||||
|
@ -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,
|
void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
||||||
scene::ICameraSceneNode * const camnode,
|
scene::ICameraSceneNode * const camnode,
|
||||||
video::SOverrideMaterial &overridemat,
|
video::SOverrideMaterial &overridemat,
|
||||||
@ -681,9 +681,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
|||||||
m_video_driver->setRenderTarget(rtts, true, false,
|
m_video_driver->setRenderTarget(rtts, true, false,
|
||||||
video::SColor(0, 0, 0, 0));
|
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);
|
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
|
||||||
PointLightProvider * const pcb = (PointLightProvider *) irr_driver->
|
PointLightProvider * const pcb = (PointLightProvider *) irr_driver->
|
||||||
getCallback(ES_POINTLIGHT);
|
getCallback(ES_POINTLIGHT);
|
||||||
@ -700,49 +697,46 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
|||||||
|
|
||||||
|
|
||||||
const u32 lightcount = m_lights.size();
|
const u32 lightcount = m_lights.size();
|
||||||
const core::vector3df &camdir = (camnode->getTarget() - camcenter).normalize();
|
const core::vector3df &campos =
|
||||||
|
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||||
float fov = camnode->getFOV() / 2.;
|
|
||||||
std::vector<float> accumulatedLightPos;
|
std::vector<float> accumulatedLightPos;
|
||||||
std::vector<float> accumulatedLightColor;
|
std::vector<float> accumulatedLightColor;
|
||||||
std::vector<float> accumulatedLightEnergy;
|
std::vector<float> accumulatedLightEnergy;
|
||||||
unsigned lightnum = 0;
|
std::vector<LightNode *> BucketedLN[15];
|
||||||
for (unsigned int i = 0; i < lightcount; i++)
|
for (unsigned int i = 0; i < lightcount; i++)
|
||||||
{
|
{
|
||||||
if (!m_lights[i]->isPointLight()) {
|
if (!m_lights[i]->isPointLight()) {
|
||||||
m_lights[i]->render();
|
m_lights[i]->render();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (lightnum >= 32)
|
const core::vector3df &lightpos = (m_lights[i]->getPosition() - campos);
|
||||||
|
unsigned idx = lightpos.getLength() / 10;
|
||||||
|
if(idx > 14)
|
||||||
continue;
|
continue;
|
||||||
// Light culling
|
BucketedLN[idx].push_back(m_lights[i]);
|
||||||
const core::vector3df &lightpos = (m_lights[i]->getPosition() - camcenter);
|
}
|
||||||
float light_radius = m_lights[i]->getRadius();
|
unsigned lightnum = 0;
|
||||||
float dotprod = camdir.dotProduct(lightpos);
|
for (unsigned i = 0; i < 15; i++) {
|
||||||
if (dotprod > 0.) {
|
for (unsigned j = 0; j < BucketedLN[i].size(); j++) {
|
||||||
// Pixels in front of camera
|
if (++lightnum > MAXLIGHT)
|
||||||
// Are they too far ?
|
break;
|
||||||
if (lightpos.getLength() > camradius)
|
LightNode *LN = BucketedLN[i].at(j);
|
||||||
continue;
|
const core::vector3df &pos = LN->getPosition();
|
||||||
// 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();
|
|
||||||
accumulatedLightPos.push_back(pos.X);
|
accumulatedLightPos.push_back(pos.X);
|
||||||
accumulatedLightPos.push_back(pos.Y);
|
accumulatedLightPos.push_back(pos.Y);
|
||||||
accumulatedLightPos.push_back(pos.Z);
|
accumulatedLightPos.push_back(pos.Z);
|
||||||
accumulatedLightPos.push_back(0.);
|
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.X);
|
||||||
accumulatedLightColor.push_back(col.Y);
|
accumulatedLightColor.push_back(col.Y);
|
||||||
accumulatedLightColor.push_back(col.Z);
|
accumulatedLightColor.push_back(col.Z);
|
||||||
accumulatedLightColor.push_back(0.);
|
accumulatedLightColor.push_back(0.);
|
||||||
accumulatedLightEnergy.push_back(m_lights[i]->getEnergy());
|
accumulatedLightEnergy.push_back(LN->getEnergy());
|
||||||
lightnum++;
|
}
|
||||||
} // for i in lights
|
if (lightnum > MAXLIGHT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy);
|
LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy);
|
||||||
// Handle SSAO
|
// Handle SSAO
|
||||||
SMaterial m_material;
|
SMaterial m_material;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user