From f9fb4a0a1742fddc32a4e1a4e0608a7b3f46d0a9 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 29 Nov 2017 00:12:15 +0100 Subject: [PATCH 1/3] - Cull back facing triangles for the span drawers --- src/polyrenderer/drawers/poly_triangle.cpp | 13 +++++++++++-- src/polyrenderer/drawers/poly_triangle.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index 386c4c630..990ca581d 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -243,6 +243,15 @@ bool PolyTriangleDrawer::is_degenerate(const ShadedTriVertex *vert) return crosslengthsqr <= 1.e-6f; } +bool PolyTriangleDrawer::is_frontfacing(TriDrawTriangleArgs *args) +{ + float a = + args->v1->x * args->v2->y - args->v2->x * args->v1->y + + args->v2->x * args->v3->y - args->v3->x * args->v2->y + + args->v3->x * args->v1->y - args->v1->x * args->v3->y; + return a <= 0.0f; +} + void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread) { // Reject triangle if degenerate @@ -324,7 +333,7 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool args->v1 = &clippedvert[numclipvert - 1]; args->v2 = &clippedvert[i - 1]; args->v3 = &clippedvert[i - 2]; - if (args->CalculateGradients()) + if (is_frontfacing(args) && args->CalculateGradients()) ScreenTriangle::Draw(args, thread); } } @@ -335,7 +344,7 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool args->v1 = &clippedvert[0]; args->v2 = &clippedvert[i - 1]; args->v3 = &clippedvert[i]; - if (args->CalculateGradients()) + if (!is_frontfacing(args) && args->CalculateGradients()) ScreenTriangle::Draw(args, thread); } } diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index eea3b8531..7ddfbed19 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -44,6 +44,7 @@ private: static void draw_arrays(const PolyDrawArgs &args, WorkerThreadData *thread); static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread); static bool is_degenerate(const ShadedTriVertex *vertices); + static bool is_frontfacing(TriDrawTriangleArgs *args); static int clipedge(const ShadedTriVertex *verts, ShadedTriVertex *clippedvert); From b621dccb9cedfe5d0602c1c0ee8e909820ef2e2b Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 29 Nov 2017 00:33:37 +0100 Subject: [PATCH 2/3] - Improve weapon hud model in the software renderer --- src/swrenderer/things/r_model.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index 710df506b..f86a7e384 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -115,6 +115,25 @@ namespace swrenderer VSMatrix SWModelRenderer::GetViewToWorldMatrix() { + // Calculate the WorldToView matrix as it would have looked like without yshearing: + const auto &Viewpoint = Thread->Viewport->viewpoint; + const auto &Viewwindow = Thread->Viewport->viewwindow; + double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians(); + double angx = cos(radPitch); + double angy = sin(radPitch) * level.info->pixelstretch; + double alen = sqrt(angx*angx + angy*angy); + float adjustedPitch = (float)asin(angy / alen); + float adjustedViewAngle = (float)(Viewpoint.Angles.Yaw - 90).Radians(); + float ratio = Viewwindow.WidescreenRatio; + float fovratio = (Viewwindow.WidescreenRatio >= 1.3f) ? 1.333333f : ratio; + float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(Viewpoint.FieldOfView.Radians() / 2) / fovratio)).Degrees); + TriMatrix altWorldToView = + TriMatrix::rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) * + TriMatrix::rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) * + TriMatrix::scale(1.0f, level.info->pixelstretch, 1.0f) * + TriMatrix::swapYZ() * + TriMatrix::translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z); + TriMatrix swapYZ = TriMatrix::null(); swapYZ.matrix[0 + 0 * 4] = 1.0f; swapYZ.matrix[1 + 2 * 4] = 1.0f; @@ -122,7 +141,7 @@ namespace swrenderer swapYZ.matrix[3 + 3 * 4] = 1.0f; VSMatrix worldToView; - worldToView.loadMatrix((Thread->Viewport->WorldToView * swapYZ).matrix); + worldToView.loadMatrix((altWorldToView * swapYZ).matrix); VSMatrix objectToWorld; worldToView.inverseMatrix(objectToWorld); From 8cad912db1747330e8f3f6113ea0f9e7f103bc2f Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 29 Nov 2017 01:09:26 +0100 Subject: [PATCH 3/3] - Add r_model_distance_cull to control when models turn into sprites --- src/swrenderer/scene/r_opaque_pass.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 3ad3ba1e0..989110e59 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -80,6 +80,7 @@ namespace { double sprite_distance_cull = 1e16; double line_distance_cull = 1e16; + double model_distance_cull = 1e16; } CUSTOM_CVAR(Float, r_sprite_distance_cull, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -106,6 +107,18 @@ CUSTOM_CVAR(Float, r_line_distance_cull, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) } } +CUSTOM_CVAR(Float, r_model_distance_cull, 1024, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/) // Experimental for the moment until a good default is chosen +{ + if (r_model_distance_cull > 0.0) + { + model_distance_cull = r_model_distance_cull * r_model_distance_cull; + } + else + { + model_distance_cull = 1e16; + } +} + namespace swrenderer { RenderOpaquePass::RenderOpaquePass(RenderThread *thread) : renderline(thread) @@ -955,7 +968,7 @@ namespace swrenderer int spritenum = thing->sprite; bool isPicnumOverride = thing->picnum.isValid(); FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); - if (modelframe) + if (modelframe && (thing->Pos() - Thread->Viewport->viewpoint.Pos).LengthSquared() < model_distance_cull) { DVector3 pos = thing->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac); RenderModel::Project(Thread, (float)pos.X, (float)pos.Y, (float)pos.Z, modelframe, thing);