mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
Improve dynamic light performance by only including lights if they touch a column or span
This commit is contained in:
parent
9a529192b0
commit
b0a96af220
2 changed files with 40 additions and 24 deletions
|
@ -274,24 +274,32 @@ void R_MapPlane (int y, int x1)
|
||||||
visplane_light *cur_node = ds_light_list;
|
visplane_light *cur_node = ds_light_list;
|
||||||
while (cur_node && nextlightindex < 64 * 1024)
|
while (cur_node && nextlightindex < 64 * 1024)
|
||||||
{
|
{
|
||||||
uint32_t red = cur_node->lightsource->GetRed();
|
|
||||||
uint32_t green = cur_node->lightsource->GetGreen();
|
|
||||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
|
||||||
|
|
||||||
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
||||||
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
||||||
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
||||||
|
|
||||||
nextlightindex++;
|
float lx = (float)(lightX * ViewSin - lightY * ViewCos);
|
||||||
auto &light = dc_lights[dc_num_lights++];
|
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
||||||
light.x = (float)(lightX * ViewSin - lightY * ViewCos);
|
float lz = (float)lightZ - dc_viewpos.Z;
|
||||||
light.y = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
|
||||||
light.z = (float)lightZ - dc_viewpos.Z;
|
|
||||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
|
||||||
light.color = (red << 16) | (green << 8) | blue;
|
|
||||||
|
|
||||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||||
light.y = light.y * light.y + light.z * light.z;
|
float lconstant = ly * ly + lz * lz;
|
||||||
|
|
||||||
|
// Include light only if it touches this row
|
||||||
|
float radius = cur_node->lightsource->GetRadius();
|
||||||
|
if (radius * radius >= lconstant)
|
||||||
|
{
|
||||||
|
uint32_t red = cur_node->lightsource->GetRed();
|
||||||
|
uint32_t green = cur_node->lightsource->GetGreen();
|
||||||
|
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||||
|
|
||||||
|
nextlightindex++;
|
||||||
|
auto &light = dc_lights[dc_num_lights++];
|
||||||
|
light.x = lx;
|
||||||
|
light.y = lconstant;
|
||||||
|
light.radius = 256.0f / radius;
|
||||||
|
light.color = (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
|
|
||||||
cur_node = cur_node->next;
|
cur_node = cur_node->next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -561,24 +561,32 @@ static void Draw1Column(int x, int y1, int y2, WallSampler &sampler, void(*draw1
|
||||||
{
|
{
|
||||||
if (!(cur_node->lightsource->flags2&MF2_DORMANT))
|
if (!(cur_node->lightsource->flags2&MF2_DORMANT))
|
||||||
{
|
{
|
||||||
uint32_t red = cur_node->lightsource->GetRed();
|
|
||||||
uint32_t green = cur_node->lightsource->GetGreen();
|
|
||||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
|
||||||
|
|
||||||
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
||||||
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
||||||
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
||||||
|
|
||||||
nextlightindex++;
|
float lx = (float)(lightX * ViewSin - lightY * ViewCos) - dc_viewpos.X;
|
||||||
auto &light = dc_lights[dc_num_lights++];
|
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
||||||
light.x = (float)(lightX * ViewSin - lightY * ViewCos) - dc_viewpos.X;
|
float lz = (float)lightZ;
|
||||||
light.y = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
|
||||||
light.z = (float)lightZ;
|
|
||||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
|
||||||
light.color = (red << 16) | (green << 8) | blue;
|
|
||||||
|
|
||||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||||
light.x = light.x * light.x + light.y * light.y;
|
float lconstant = lx * lx + ly * ly;
|
||||||
|
|
||||||
|
// Include light only if it touches this column
|
||||||
|
float radius = cur_node->lightsource->GetRadius();
|
||||||
|
if (radius * radius >= lconstant)
|
||||||
|
{
|
||||||
|
uint32_t red = cur_node->lightsource->GetRed();
|
||||||
|
uint32_t green = cur_node->lightsource->GetGreen();
|
||||||
|
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||||
|
|
||||||
|
nextlightindex++;
|
||||||
|
auto &light = dc_lights[dc_num_lights++];
|
||||||
|
light.x = lconstant;
|
||||||
|
light.z = lz;
|
||||||
|
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||||
|
light.color = (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_node = cur_node->nextLight;
|
cur_node = cur_node->nextLight;
|
||||||
|
|
Loading…
Reference in a new issue