mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 22:11:43 +00:00
Fix misc bugs for dynamic lights in the pal slope drawer
This commit is contained in:
parent
18bc384807
commit
99f2b5d891
3 changed files with 35 additions and 32 deletions
|
@ -1823,7 +1823,7 @@ namespace swrenderer
|
||||||
// Screen space to view space
|
// Screen space to view space
|
||||||
viewpos_z = 1.0f / viewpos_z;
|
viewpos_z = 1.0f / viewpos_z;
|
||||||
viewpos_x *= viewpos_z;
|
viewpos_x *= viewpos_z;
|
||||||
viewpos_y *= viewpos_y;
|
viewpos_y *= viewpos_z;
|
||||||
|
|
||||||
for (int i = 0; i < num_lights; i++)
|
for (int i = 0; i < num_lights; i++)
|
||||||
{
|
{
|
||||||
|
@ -1843,8 +1843,15 @@ namespace swrenderer
|
||||||
#else
|
#else
|
||||||
float rcp_dist = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_load_ss(&dist2)));
|
float rcp_dist = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_load_ss(&dist2)));
|
||||||
#endif
|
#endif
|
||||||
|
Lx *= rcp_dist;
|
||||||
|
Ly *= rcp_dist;
|
||||||
|
Lz *= rcp_dist;
|
||||||
float dist = dist2 * rcp_dist;
|
float dist = dist2 * rcp_dist;
|
||||||
float distance_attenuation = (256.0f - min(dist * lights[i].radius, 256.0f));
|
float radius = lights[i].radius;
|
||||||
|
bool simpleType = radius < 0.0f;
|
||||||
|
if (simpleType)
|
||||||
|
radius = -radius;
|
||||||
|
float distance_attenuation = (256.0f - min(dist * radius, 256.0f));
|
||||||
|
|
||||||
// The simple light type
|
// The simple light type
|
||||||
float simple_attenuation = distance_attenuation;
|
float simple_attenuation = distance_attenuation;
|
||||||
|
@ -1852,8 +1859,8 @@ namespace swrenderer
|
||||||
// The point light type
|
// The point light type
|
||||||
// diffuse = dot(N,L) * attenuation
|
// diffuse = dot(N,L) * attenuation
|
||||||
float dotNL = max(nx * Lx + ny * Ly + nz * Lz, 0.0f);
|
float dotNL = max(nx * Lx + ny * Ly + nz * Lz, 0.0f);
|
||||||
float point_attenuation = dotNL * rcp_dist * distance_attenuation;
|
float point_attenuation = dotNL * distance_attenuation;
|
||||||
uint32_t attenuation = (uint32_t)(lights[i].z == 0.0f ? simple_attenuation : point_attenuation);
|
uint32_t attenuation = (uint32_t)(simpleType ? simple_attenuation : point_attenuation);
|
||||||
|
|
||||||
lit_r += (light_color_r * attenuation) >> 8;
|
lit_r += (light_color_r * attenuation) >> 8;
|
||||||
lit_g += (light_color_g * attenuation) >> 8;
|
lit_g += (light_color_g * attenuation) >> 8;
|
||||||
|
@ -2855,7 +2862,7 @@ namespace swrenderer
|
||||||
auto num_lights = args.dc_num_lights;
|
auto num_lights = args.dc_num_lights;
|
||||||
auto normal = args.dc_normal;
|
auto normal = args.dc_normal;
|
||||||
auto viewpos = args.dc_viewpos;
|
auto viewpos = args.dc_viewpos;
|
||||||
auto dc_viewpos_step = args.dc_viewpos_step;
|
auto viewpos_step = args.dc_viewpos_step;
|
||||||
while (width >= SPANSIZE)
|
while (width >= SPANSIZE)
|
||||||
{
|
{
|
||||||
iz += izstep;
|
iz += izstep;
|
||||||
|
@ -2878,7 +2885,7 @@ namespace swrenderer
|
||||||
x1++;
|
x1++;
|
||||||
u += stepu;
|
u += stepu;
|
||||||
v += stepv;
|
v += stepv;
|
||||||
viewpos += dc_viewpos_step;
|
viewpos += viewpos_step;
|
||||||
}
|
}
|
||||||
startu = endu;
|
startu = endu;
|
||||||
startv = endv;
|
startv = endv;
|
||||||
|
@ -2918,7 +2925,7 @@ namespace swrenderer
|
||||||
x1++;
|
x1++;
|
||||||
u += stepu;
|
u += stepu;
|
||||||
v += stepv;
|
v += stepv;
|
||||||
viewpos += dc_viewpos_step;
|
viewpos += viewpos_step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,11 +88,14 @@ namespace swrenderer
|
||||||
|
|
||||||
auto viewport = Thread->Viewport.get();
|
auto viewport = Thread->Viewport.get();
|
||||||
|
|
||||||
DVector3 worldNormal = pl->height.Normal();
|
// Stupid way of doing it, but at least it works
|
||||||
planeNormal.X = worldNormal.X * viewport->viewpoint.Sin - worldNormal.Y * viewport->viewpoint.Cos;
|
DVector3 worldP0(viewport->viewpoint.Pos, pl->height.ZatPoint(viewport->viewpoint.Pos));
|
||||||
planeNormal.Y = worldNormal.X * viewport->viewpoint.Cos + worldNormal.Y * viewport->viewpoint.Sin;
|
DVector3 worldP1 = worldP0 + pl->height.Normal();
|
||||||
planeNormal.Z = worldNormal.Z;
|
DVector3 viewP0 = viewport->PointWorldToView(worldP0);
|
||||||
planeD = -planeNormal.Z * (pl->height.ZatPoint(viewport->viewpoint.Pos.X, viewport->viewpoint.Pos.Y) - viewport->viewpoint.Pos.Z);
|
DVector3 viewP1 = viewport->PointWorldToView(worldP1);
|
||||||
|
planeNormal = viewP1 - viewP0;
|
||||||
|
planeD = -(viewP0 | planeNormal);
|
||||||
|
|
||||||
if (Thread->Portal->MirrorFlags & RF_XFLIP)
|
if (Thread->Portal->MirrorFlags & RF_XFLIP)
|
||||||
planeNormal.X = -planeNormal.X;
|
planeNormal.X = -planeNormal.X;
|
||||||
|
|
||||||
|
@ -209,11 +212,6 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
if (r_dynlights)
|
if (r_dynlights)
|
||||||
{
|
{
|
||||||
int tx = x1;
|
|
||||||
bool mirror = !!(Thread->Portal->MirrorFlags & RF_XFLIP);
|
|
||||||
if (mirror)
|
|
||||||
tx = viewwidth - tx - 1;
|
|
||||||
|
|
||||||
// Find row position in view space
|
// Find row position in view space
|
||||||
DVector3 viewposX1 = Thread->Viewport->ScreenToViewPos(x1, y, planeNormal, planeD);
|
DVector3 viewposX1 = Thread->Viewport->ScreenToViewPos(x1, y, planeNormal, planeD);
|
||||||
DVector3 viewposX2 = Thread->Viewport->ScreenToViewPos(x2, y, planeNormal, planeD);
|
DVector3 viewposX2 = Thread->Viewport->ScreenToViewPos(x2, y, planeNormal, planeD);
|
||||||
|
@ -229,9 +227,9 @@ namespace swrenderer
|
||||||
drawerargs.dc_viewpos.X = viewposX1.X;
|
drawerargs.dc_viewpos.X = viewposX1.X;
|
||||||
drawerargs.dc_viewpos.Y = viewposX1.Y;
|
drawerargs.dc_viewpos.Y = viewposX1.Y;
|
||||||
drawerargs.dc_viewpos.Z = viewposX1.Z;
|
drawerargs.dc_viewpos.Z = viewposX1.Z;
|
||||||
drawerargs.dc_viewpos_step.X = viewposX2.X - viewposX1.X;
|
drawerargs.dc_viewpos_step.X = (viewposX2.X - viewposX1.X) / (x2 - x1);
|
||||||
drawerargs.dc_viewpos_step.Y = viewposX2.Y - viewposX1.Y;
|
drawerargs.dc_viewpos_step.Y = (viewposX2.Y - viewposX1.Y) / (x2 - x1);
|
||||||
drawerargs.dc_viewpos_step.Z = viewposX2.Z - viewposX1.Z;
|
drawerargs.dc_viewpos_step.Z = (viewposX2.Z - viewposX1.Z) / (x2 - x1);
|
||||||
|
|
||||||
// Plane normal
|
// Plane normal
|
||||||
drawerargs.dc_normal.X = planeNormal.X;
|
drawerargs.dc_normal.X = planeNormal.X;
|
||||||
|
@ -257,24 +255,22 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
if (cur_node->lightsource->IsActive())
|
if (cur_node->lightsource->IsActive())
|
||||||
{
|
{
|
||||||
double lightX = cur_node->lightsource->X() - Thread->Viewport->viewpoint.Pos.X;
|
DVector3 lightPos = Thread->Viewport->PointWorldToView(cur_node->lightsource->Pos);
|
||||||
double lightY = cur_node->lightsource->Y() - Thread->Viewport->viewpoint.Pos.Y;
|
|
||||||
double lightZ = cur_node->lightsource->Z() - Thread->Viewport->viewpoint.Pos.Z;
|
|
||||||
|
|
||||||
float lx = (float)(lightX * Thread->Viewport->viewpoint.Sin - lightY * Thread->Viewport->viewpoint.Cos);
|
|
||||||
float ly = (float)(lightX * Thread->Viewport->viewpoint.TanCos + lightY * Thread->Viewport->viewpoint.TanSin);
|
|
||||||
float lz = (float)lightZ;
|
|
||||||
|
|
||||||
uint32_t red = cur_node->lightsource->GetRed();
|
uint32_t red = cur_node->lightsource->GetRed();
|
||||||
uint32_t green = cur_node->lightsource->GetGreen();
|
uint32_t green = cur_node->lightsource->GetGreen();
|
||||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||||
|
|
||||||
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||||
light.x = lx;
|
light.x = lightPos.X;
|
||||||
light.y = ly;
|
light.y = lightPos.Y;
|
||||||
light.z = lz;
|
light.z = lightPos.Z;
|
||||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||||
light.color = (red << 16) | (green << 8) | blue;
|
light.color = (red << 16) | (green << 8) | blue;
|
||||||
|
|
||||||
|
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||||
|
if (is_point_light)
|
||||||
|
light.radius = -light.radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_node = cur_node->next;
|
cur_node = cur_node->next;
|
||||||
|
|
|
@ -254,7 +254,7 @@ namespace swrenderer
|
||||||
double translatedY = worldPos.Y - viewpoint.Pos.Y;
|
double translatedY = worldPos.Y - viewpoint.Pos.Y;
|
||||||
return {
|
return {
|
||||||
translatedX * viewpoint.Sin - translatedY * viewpoint.Cos,
|
translatedX * viewpoint.Sin - translatedY * viewpoint.Cos,
|
||||||
translatedX * viewpoint.TanCos + translatedY * viewpoint.TanSin
|
translatedX * viewpoint.Cos + translatedY * viewpoint.Sin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ namespace swrenderer
|
||||||
return {
|
return {
|
||||||
translatedX * viewpoint.Sin - translatedY * viewpoint.Cos,
|
translatedX * viewpoint.Sin - translatedY * viewpoint.Cos,
|
||||||
translatedZ,
|
translatedZ,
|
||||||
translatedX * viewpoint.TanCos + translatedY * viewpoint.TanSin
|
translatedX * viewpoint.Cos + translatedY * viewpoint.Sin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue