diff --git a/src/p_maputl.c b/src/p_maputl.c
index 18a15a9282e7fc5d67975cb46012a820cbc44ccb..3373a40c430648a5900104253e2bd571e54d6490 100644
--- a/src/p_maputl.c
+++ b/src/p_maputl.c
@@ -541,16 +541,18 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
 				if (delta1 > delta2) { // Below
 					if (opentop > texbottom) {
 						opentop = texbottom;
-						if ((linedef->flags & ML_MIDPEG) != 0) {
-							opentopslope = openbottomslope;
-						}
+						if (linedef->flags & ML_NOSKEW)
+							opentopslope = NULL;
+						else
+							opentopslope = linedef->midtexslope;
 					}
 				} else { // Above
 					if (openbottom < textop) {
 						openbottom = textop;
-						if ((linedef->flags & ML_MIDPEG) == 0) {
-							openbottomslope = opentopslope;
-						}
+						if (linedef->flags & ML_NOSKEW)
+							openbottomslope = NULL;
+						else
+							openbottomslope = linedef->midtexslope;
 					}
 				}
 			}
diff --git a/src/p_setup.c b/src/p_setup.c
index 41487d702f265c7e5164c61be8d0b8f8c059aa38..3dd3d942cd23e4c308fe81b52f8723be5884a19b 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1113,6 +1113,8 @@ static void P_InitializeLinedef(line_t *ld)
 	ld->callcount = 0;
 	ld->secportal = UINT32_MAX;
 
+	ld->midtexslope = NULL;
+
 	// cph 2006/09/30 - fix sidedef errors right away.
 	// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
 	for (j = 0; j < 2; j++)
diff --git a/src/p_slopes.c b/src/p_slopes.c
index e75d36edefe8d8484cb0c9bebb4d02d5f1b1e174..d941c71f937f644c01fd47e153a12ff21904f17e 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -28,6 +28,8 @@
 pslope_t *slopelist = NULL;
 UINT16 slopecount = 0;
 
+static void P_UpdateMidtextureSlopesForSector(sector_t *sector);
+
 // Calculate line normal
 void P_CalculateSlopeNormal(pslope_t *slope)
 {
@@ -212,6 +214,9 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th)
 		slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta);
 		slope->moved = true;
 		P_CalculateSlopeNormal(slope);
+		P_UpdateMidtextureSlopesForSector(srcline->frontsector);
+		if (srcline->backsector)
+			P_UpdateMidtextureSlopesForSector(srcline->backsector);
 	}
 }
 
@@ -232,6 +237,12 @@ void T_DynamicSlopeVert (dynvertexplanethink_t* th)
 	}
 
 	ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]);
+
+	for (i = 0; i < 3; i++)
+	{
+		if (th->secs[i])
+			P_UpdateMidtextureSlopesForSector(th->secs[i]);
+	}
 }
 
 static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent)
@@ -758,6 +769,111 @@ pslope_t *P_MakeSlopeViaEquationConstants(const double a, const double b, const
 	return ret;
 }
 
+static pslope_t *P_GetReferenceSlopeForMidtexture(line_t *line)
+{
+	if (line->flags & ML_MIDPEG)
+	{
+		// Line has ML_MIDPEG, so use the floor slope
+		fixed_t frontheight = P_GetSectorFloorZAt(line->frontsector, line->v1->x, line->v1->y);
+		fixed_t backheight = P_GetSectorFloorZAt(line->backsector, line->v1->x, line->v1->y);
+
+		if (frontheight > backheight)
+		{
+			return line->frontsector->f_slope;
+		}
+		else
+		{
+			return line->backsector->f_slope;
+		}
+	}
+	else
+	{
+		// Line does not have ML_MIDPEG, so use the ceiling slope
+		fixed_t frontheight = P_GetSectorCeilingZAt(line->frontsector, line->v1->x, line->v1->y);
+		fixed_t backheight = P_GetSectorCeilingZAt(line->backsector, line->v1->x, line->v1->y);
+
+		if (frontheight < backheight)
+		{
+			return line->frontsector->c_slope;
+		}
+		else
+		{
+			return line->backsector->c_slope;
+		}
+	}
+
+	return NULL;
+}
+
+// Updates a slope for a solid midtexture based on the slope of the sector it's in.
+static void P_UpdateSolidMidtextureSlope(line_t *line, pslope_t *ref)
+{
+	pslope_t *slope = line->midtexslope;
+
+	if (ref == NULL)
+		return;
+
+	// Set origin
+	vector3_t origin;
+	origin.x = line->v1->x;
+	origin.y = line->v1->y;
+	origin.z = P_GetSlopeZAt(ref, origin.x, origin.y);
+	FV3_Copy(&slope->o, &origin);
+
+	// Get where the line ends
+	vector3_t point;
+	point.x = line->v2->x;
+	point.y = line->v2->y;
+	point.z = P_GetSlopeZAt(ref, point.x, point.y);
+
+	// Get length of the line
+	fixed_t extent = R_PointToDist2(0, 0, line->dx, line->dy);
+
+	// Precalculate variables
+	slope->zdelta = FixedDiv(origin.z - point.z, extent);
+	slope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
+	slope->xydirection = line->angle;
+
+	// Precalculate the direction
+	vector2_t dir;
+	dir.x = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINECOSINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT));
+	dir.y = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINESINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT));
+	FV2_Copy(&slope->d, &dir);
+
+	P_CalculateSlopeNormal(slope);
+
+	// Calling P_CalculateSlopeVectors is not necessary.
+	slope->moved = true;
+}
+
+// Goes through every line in the sector and updates the midtexture slope if it is present
+static void P_UpdateMidtextureSlopesForSector(sector_t *sector)
+{
+	for (size_t i = 0; i < sector->linecount; i++)
+	{
+		if (sector->lines[i]->midtexslope != NULL)
+			P_UpdateSolidMidtextureSlope(sector->lines[i], P_GetReferenceSlopeForMidtexture(sector->lines[i]));
+	}
+}
+
+// Creates a solid midtexture slope for the line if possible
+static void P_CreateSolidMidtextureSlope(line_t *line)
+{
+	if (line->backsector == NULL) // Ignore single-sided lines (of course)
+		return;
+
+	if ((line->flags & ML_MIDSOLID) == 0) // Ignore if the midtexture is not solid
+		return;
+
+	pslope_t *ref = P_GetReferenceSlopeForMidtexture(line);
+	if (ref)
+	{
+		line->midtexslope = Slope_Add(0);
+
+		P_UpdateSolidMidtextureSlope(line, ref);
+	}
+}
+
 /// Initializes and reads the slopes from the map data.
 void P_SpawnSlopes(const boolean fromsave) {
 	size_t i;
@@ -785,14 +901,21 @@ void P_SpawnSlopes(const boolean fromsave) {
 
 	/// Copies slopes from tagged sectors via line specials.
 	/// \note Doesn't actually copy, but instead they share the same pointers.
+	// Also, creates midtexture slopes.
 	for (i = 0; i < numlines; i++)
-		switch (lines[i].special)
+	{
+		line_t *line = &lines[i];
+
+		switch (line->special)
 		{
 			case 720:
-				P_CopySectorSlope(&lines[i]);
+				P_CopySectorSlope(line);
 			default:
 				break;
 		}
+
+		P_CreateSolidMidtextureSlope(line);
+	}
 }
 
 /// Initializes slopes.
diff --git a/src/r_defs.h b/src/r_defs.h
index da4dd2d70e6049479eacd24c51af11b4a995507b..7a6f518ee26ca96a4a4df62f30ec7dc741855bcd 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -612,6 +612,8 @@ typedef struct line_s
 	INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
 
 	UINT32 secportal; // transferred sector portal
+
+	struct pslope_s *midtexslope;
 } line_t;
 
 typedef struct