mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +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
|
||||
viewpos_z = 1.0f / viewpos_z;
|
||||
viewpos_x *= viewpos_z;
|
||||
viewpos_y *= viewpos_y;
|
||||
viewpos_y *= viewpos_z;
|
||||
|
||||
for (int i = 0; i < num_lights; i++)
|
||||
{
|
||||
|
@ -1843,8 +1843,15 @@ namespace swrenderer
|
|||
#else
|
||||
float rcp_dist = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_load_ss(&dist2)));
|
||||
#endif
|
||||
Lx *= rcp_dist;
|
||||
Ly *= rcp_dist;
|
||||
Lz *= 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
|
||||
float simple_attenuation = distance_attenuation;
|
||||
|
@ -1852,8 +1859,8 @@ namespace swrenderer
|
|||
// The point light type
|
||||
// diffuse = dot(N,L) * attenuation
|
||||
float dotNL = max(nx * Lx + ny * Ly + nz * Lz, 0.0f);
|
||||
float point_attenuation = dotNL * rcp_dist * distance_attenuation;
|
||||
uint32_t attenuation = (uint32_t)(lights[i].z == 0.0f ? simple_attenuation : point_attenuation);
|
||||
float point_attenuation = dotNL * distance_attenuation;
|
||||
uint32_t attenuation = (uint32_t)(simpleType ? simple_attenuation : point_attenuation);
|
||||
|
||||
lit_r += (light_color_r * attenuation) >> 8;
|
||||
lit_g += (light_color_g * attenuation) >> 8;
|
||||
|
@ -2855,7 +2862,7 @@ namespace swrenderer
|
|||
auto num_lights = args.dc_num_lights;
|
||||
auto normal = args.dc_normal;
|
||||
auto viewpos = args.dc_viewpos;
|
||||
auto dc_viewpos_step = args.dc_viewpos_step;
|
||||
auto viewpos_step = args.dc_viewpos_step;
|
||||
while (width >= SPANSIZE)
|
||||
{
|
||||
iz += izstep;
|
||||
|
@ -2878,7 +2885,7 @@ namespace swrenderer
|
|||
x1++;
|
||||
u += stepu;
|
||||
v += stepv;
|
||||
viewpos += dc_viewpos_step;
|
||||
viewpos += viewpos_step;
|
||||
}
|
||||
startu = endu;
|
||||
startv = endv;
|
||||
|
@ -2918,7 +2925,7 @@ namespace swrenderer
|
|||
x1++;
|
||||
u += stepu;
|
||||
v += stepv;
|
||||
viewpos += dc_viewpos_step;
|
||||
viewpos += viewpos_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,11 +88,14 @@ namespace swrenderer
|
|||
|
||||
auto viewport = Thread->Viewport.get();
|
||||
|
||||
DVector3 worldNormal = pl->height.Normal();
|
||||
planeNormal.X = worldNormal.X * viewport->viewpoint.Sin - worldNormal.Y * viewport->viewpoint.Cos;
|
||||
planeNormal.Y = worldNormal.X * viewport->viewpoint.Cos + worldNormal.Y * viewport->viewpoint.Sin;
|
||||
planeNormal.Z = worldNormal.Z;
|
||||
planeD = -planeNormal.Z * (pl->height.ZatPoint(viewport->viewpoint.Pos.X, viewport->viewpoint.Pos.Y) - viewport->viewpoint.Pos.Z);
|
||||
// Stupid way of doing it, but at least it works
|
||||
DVector3 worldP0(viewport->viewpoint.Pos, pl->height.ZatPoint(viewport->viewpoint.Pos));
|
||||
DVector3 worldP1 = worldP0 + pl->height.Normal();
|
||||
DVector3 viewP0 = viewport->PointWorldToView(worldP0);
|
||||
DVector3 viewP1 = viewport->PointWorldToView(worldP1);
|
||||
planeNormal = viewP1 - viewP0;
|
||||
planeD = -(viewP0 | planeNormal);
|
||||
|
||||
if (Thread->Portal->MirrorFlags & RF_XFLIP)
|
||||
planeNormal.X = -planeNormal.X;
|
||||
|
||||
|
@ -209,11 +212,6 @@ namespace swrenderer
|
|||
{
|
||||
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
|
||||
DVector3 viewposX1 = Thread->Viewport->ScreenToViewPos(x1, 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.Y = viewposX1.Y;
|
||||
drawerargs.dc_viewpos.Z = viewposX1.Z;
|
||||
drawerargs.dc_viewpos_step.X = viewposX2.X - viewposX1.X;
|
||||
drawerargs.dc_viewpos_step.Y = viewposX2.Y - viewposX1.Y;
|
||||
drawerargs.dc_viewpos_step.Z = viewposX2.Z - viewposX1.Z;
|
||||
drawerargs.dc_viewpos_step.X = (viewposX2.X - viewposX1.X) / (x2 - x1);
|
||||
drawerargs.dc_viewpos_step.Y = (viewposX2.Y - viewposX1.Y) / (x2 - x1);
|
||||
drawerargs.dc_viewpos_step.Z = (viewposX2.Z - viewposX1.Z) / (x2 - x1);
|
||||
|
||||
// Plane normal
|
||||
drawerargs.dc_normal.X = planeNormal.X;
|
||||
|
@ -257,24 +255,22 @@ namespace swrenderer
|
|||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
{
|
||||
double lightX = cur_node->lightsource->X() - Thread->Viewport->viewpoint.Pos.X;
|
||||
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;
|
||||
DVector3 lightPos = Thread->Viewport->PointWorldToView(cur_node->lightsource->Pos);
|
||||
|
||||
uint32_t red = cur_node->lightsource->GetRed();
|
||||
uint32_t green = cur_node->lightsource->GetGreen();
|
||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||
|
||||
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||
light.x = lx;
|
||||
light.y = ly;
|
||||
light.z = lz;
|
||||
light.x = lightPos.X;
|
||||
light.y = lightPos.Y;
|
||||
light.z = lightPos.Z;
|
||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||
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;
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace swrenderer
|
|||
double translatedY = worldPos.Y - viewpoint.Pos.Y;
|
||||
return {
|
||||
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 {
|
||||
translatedX * viewpoint.Sin - translatedY * viewpoint.Cos,
|
||||
translatedZ,
|
||||
translatedX * viewpoint.TanCos + translatedY * viewpoint.TanSin
|
||||
translatedX * viewpoint.Cos + translatedY * viewpoint.Sin
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue