diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 042b8e90b2d4ea7a5936147e74c6fe0b2af4a9e7..610ad492b875f459ec275049449ad30c53ebb2c8 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -1543,6 +1543,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 		INT32 gr_toptexture = 0, gr_bottomtexture = 0;
 		// two sided line
 		boolean bothceilingssky = false; // turned on if both back and front ceilings are sky
+		boolean bothfloorssky = false; // likewise, but for floors
 
 #ifdef ESLOPE
 		SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight)
@@ -1561,9 +1562,17 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
 			bothceilingssky = true;
 		}
 
+		// likewise, but for floors and upper textures
+		if (gr_frontsector->floorpic == skyflatnum
+			&& gr_backsector->floorpic == skyflatnum)
+		{
+			bothfloorssky = true;
+		}
+
 		if (!bothceilingssky)
 			gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture);
-		gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture);
+		if (!bothfloorssky)
+			gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture);
 
 		// check TOP TEXTURE
 		if ((
@@ -2457,7 +2466,9 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
 		backc1 = backc2 = abacksector->ceilingheight;
 	}
 	// properly render skies (consider door "open" if both ceilings are sky)
-	if (abacksector->ceilingpic != skyflatnum || afrontsector->ceilingpic != skyflatnum)
+	// same for floors
+	if ((abacksector->ceilingpic != skyflatnum || afrontsector->ceilingpic != skyflatnum)
+	 && (abacksector->floorpic != skyflatnum   || afrontsector->floorpic != skyflatnum))
 	{
 		// now check for closed sectors!
 		if ((backc1 <= frontf1 && backc2 <= frontf2)
@@ -2953,8 +2964,10 @@ static void HWR_AddLine(seg_t * line)
 		SLOPEPARAMS( gr_backsector->f_slope, backf1,  backf2,  gr_backsector->floorheight)
 		SLOPEPARAMS( gr_backsector->c_slope, backc1,  backc2,  gr_backsector->ceilingheight)
 #undef SLOPEPARAMS
-
-		if (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)
+		// if both ceilings are skies, consider it always "open"
+		// same for floors
+		if ((gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)
+		 && (gr_backsector->floorpic != skyflatnum   || gr_frontsector->floorpic != skyflatnum))
 		{
 			// Closed door.
 			if ((backc1 <= frontf1 && backc2 <= frontf2)
@@ -2980,8 +2993,10 @@ static void HWR_AddLine(seg_t * line)
 	else
 #endif
 	{
-
-		if (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)
+		// if both ceilings are skies, consider it always "open"
+		// same for floors
+		if ((gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)
+		 && (gr_backsector->floorpic != skyflatnum   || gr_frontsector->floorpic != skyflatnum))
 		{
 			// Closed door.
 			if (gr_backsector->ceilingheight <= gr_frontsector->floorheight ||
diff --git a/src/r_bsp.c b/src/r_bsp.c
index 3cfad154972d9f124e0e37951ae4d7a47067df48..5b0a4ca3672ee7c6f51f164c4428c1486db835b7 100644
--- a/src/r_bsp.c
+++ b/src/r_bsp.c
@@ -506,7 +506,9 @@ static void R_AddLine(seg_t *line)
 		SLOPEPARAMS( backsector->c_slope, backc1,  backc2,  backsector->ceilingheight)
 #undef SLOPEPARAMS
 		// if both ceilings are skies, consider it always "open"
-		if (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)
+		// same for floors
+		if ((backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)
+		 && (backsector->floorpic != skyflatnum   || frontsector->floorpic != skyflatnum))
 		{
 			if ((backc1 <= frontf1 && backc2 <= frontf2)
 				|| (backf1 >= frontc1 && backf2 >= frontc2))
@@ -534,7 +536,9 @@ static void R_AddLine(seg_t *line)
 #endif
 	{
 		// if both ceilings are skies, consider it always "open"
-		if (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)
+		// same for floors
+		if ((backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)
+		 && (backsector->floorpic != skyflatnum   || frontsector->floorpic != skyflatnum))
 		{
 			if (backsector->ceilingheight <= frontsector->floorheight
 				|| backsector->floorheight >= frontsector->ceilingheight)
@@ -926,7 +930,8 @@ static void R_Subsector(size_t num)
 #ifdef ESLOPE
 			frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) :
 #endif
-		frontsector->floorheight) < viewz || (frontsector->heightsec != -1
+		frontsector->floorheight) < viewz || frontsector->floorpic == skyflatnum
+		|| (frontsector->heightsec != -1
 		&& sectors[frontsector->heightsec].ceilingpic == skyflatnum)))
 	{
 		floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
diff --git a/src/r_segs.c b/src/r_segs.c
index 6ed1417d8ebdc2bb7f01a711d6672bc417ac2d18..ff3a956adff64ecb3e6519c8032bd2d777dcf14b 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -2016,6 +2016,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 	{
 		// two sided line
 		boolean bothceilingssky = false; // turned on if both back and front ceilings are sky
+		boolean bothfloorssky = false; // likewise, but for floors
 
 #ifdef ESLOPE
 		SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight)
@@ -2037,34 +2038,44 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 			bothceilingssky = true;
 		}
 
+		// likewise, but for floors and upper textures
+		if (frontsector->floorpic == skyflatnum
+			&& backsector->floorpic == skyflatnum)
+		{
+			bothfloorssky = true;
+		}
+
 		ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
 		ds_p->silhouette = 0;
 
-		if (
+		if (!bothfloorssky)
+		{
+			if (
 #ifdef ESLOPE
-			worldbottomslope > worldlowslope ||
+				worldbottomslope > worldlowslope ||
 #endif
-			worldbottom > worldlow)
-		{
-			ds_p->silhouette = SIL_BOTTOM;
+				worldbottom > worldlow)
+			{
+				ds_p->silhouette = SIL_BOTTOM;
 #ifdef ESLOPE
-			if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz)
-				ds_p->bsilheight = INT32_MAX;
-			else
-				ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight);
+				if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz)
+					ds_p->bsilheight = INT32_MAX;
+				else
+					ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight);
 #else
-			ds_p->bsilheight = frontsector->floorheight;
+				ds_p->bsilheight = frontsector->floorheight;
 #endif
-		}
+			}
 #ifdef ESLOPE
-		else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz)
+			else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz)
 #else
-		else if (backsector->floorheight > viewz)
+			else if (backsector->floorheight > viewz)
 #endif
-		{
-			ds_p->silhouette = SIL_BOTTOM;
-			ds_p->bsilheight = INT32_MAX;
-			// ds_p->sprbottomclip = negonearray;
+			{
+				ds_p->silhouette = SIL_BOTTOM;
+				ds_p->bsilheight = INT32_MAX;
+				// ds_p->sprbottomclip = negonearray;
+			}
 		}
 
 		if (!bothceilingssky)
@@ -2097,7 +2108,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 			}
 		}
 
-		if (!bothceilingssky)
+		if (!bothceilingssky && !bothfloorssky)
 		{
 #ifdef ESLOPE
 			if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)
@@ -2125,7 +2136,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 		//SoM: 3/25/2000: This code fixes an automap bug that didn't check
 		// frontsector->ceiling and backsector->floor to see if a door was closed.
 		// Without the following code, sprites get displayed behind closed doors.
-		if (!bothceilingssky)
+		if (!bothceilingssky && !bothfloorssky)
 		{
 #ifdef ESLOPE
 			if (doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope))
@@ -2149,7 +2160,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 			}
 		}
 
-		if (worldlow != worldbottom
+		if (bothfloorssky)
+		{
+			// see double ceiling skies comment
+			// this is the same but for upside down thok barriers where the floor is sky and the ceiling is normal
+			markfloor = false;
+		}
+		else if (worldlow != worldbottom
 #ifdef ESLOPE
 			|| worldlowslope != worldbottomslope
 			|| backsector->f_slope != frontsector->f_slope
@@ -2161,7 +2178,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 		    || backsector->floor_yoffs != frontsector->floor_yoffs
 		    || backsector->floorpic_angle != frontsector->floorpic_angle
 		    //SoM: 3/22/2000: Prevents bleeding.
-		    || frontsector->heightsec != -1
+		    || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum)
 		    || backsector->floorlightsec != frontsector->floorlightsec
 		    //SoM: 4/3/2000: Check for colormaps
 		    || frontsector->extra_colormap != backsector->extra_colormap
@@ -2208,7 +2225,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 			markceiling = false;
 		}
 
-		if (!bothceilingssky)
+		if (!bothceilingssky && !bothfloorssky)
 		{
 #ifdef ESLOPE
 			if ((worldhigh <= worldbottom && worldhighslope <= worldbottomslope)
@@ -2278,11 +2295,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 			}
 		}
 		// check BOTTOM TEXTURE
-		if (worldlow > worldbottom
+		if (!bothfloorssky // never draw the bottom texture if on
+			&& (worldlow > worldbottom
 #ifdef ESLOPE
 				|| worldlowslope > worldbottomslope
 #endif
-			)     //seulement si VISIBLE!!!
+			))     //seulement si VISIBLE!!!
 		{
 			// bottom texture
 			bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
@@ -2636,7 +2654,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
 	//  and doesn't need to be marked.
 	if (frontsector->heightsec == -1)
 	{
-		if ((
+		if (frontsector->floorpic != skyflatnum
+		&& (
 #ifdef ESLOPE
 			frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) :
 #endif