diff --git a/src/r_draw.h b/src/r_draw.h
index fa2cb22d077a35a785d25a564c75c4ee77eb92ac..1116e1c2585a080d5225b03d8cbe70ae296c9124 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -149,6 +149,7 @@ void R_DrawTranslatedTranslucentColumn_8(void);
 void R_DrawSpan_8(void);
 #ifdef ESLOPE
 void R_DrawTiltedSpan_8(void);
+void R_DrawTiltedTranslucentSpan_8(void);
 #endif
 void R_DrawSplat_8(void);
 void R_DrawTranslucentSplat_8(void);
diff --git a/src/r_draw8.c b/src/r_draw8.c
index b8b23b1b3299041957c8365999cbe8aa4ca08bf8..a028b9c12703f9b99b0d0537d641ec15ff2bef57 100644
--- a/src/r_draw8.c
+++ b/src/r_draw8.c
@@ -682,6 +682,139 @@ void R_DrawTiltedSpan_8(void)
 	}
 #endif
 }
+
+
+/**	\brief The R_DrawTiltedTranslucentSpan_8 function
+	Like DrawTiltedSpan, but translucent
+*/
+void R_DrawTiltedTranslucentSpan_8(void)
+{
+	// x1, x2 = ds_x1, ds_x2
+	int width = ds_x2 - ds_x1;
+	double iz, uz, vz;
+	UINT32 u, v;
+	int i;
+
+	UINT8 *source;
+	UINT8 *colormap;
+	UINT8 *dest;
+
+	iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
+
+	// Lighting is simple. It's just linear interpolation from start to end
+	{
+		float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
+		float lightstart, lightend;
+
+		lightend = (iz + ds_sz.x*width) * planelightfloat;
+		lightstart = iz * planelightfloat;
+
+		R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
+		//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
+	}
+
+	uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
+	vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
+
+	dest = ylookup[ds_y] + columnofs[ds_x1];
+	source = ds_source;
+	//colormap = ds_colormap;
+
+#if 0	// The "perfect" reference version of this routine. Pretty slow.
+		// Use it only to see how things are supposed to look.
+	i = 0;
+	do
+	{
+		double z = 1.f/iz;
+		u = (UINT32)(uz*z) + viewx;
+		v = (UINT32)(vz*z) + viewy;
+
+		colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+
+		*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+		dest++;
+		iz += ds_sz.x;
+		uz += ds_su.x;
+		vz += ds_sv.x;
+	} while (--width >= 0);
+#else
+#define SPANSIZE 16
+#define INVSPAN	0.0625f
+
+	double startz = 1.f/iz;
+	double startu = uz*startz;
+	double startv = vz*startz;
+	double izstep, uzstep, vzstep;
+
+	izstep = ds_sz.x * SPANSIZE;
+	uzstep = ds_su.x * SPANSIZE;
+	vzstep = ds_sv.x * SPANSIZE;
+	//x1 = 0;
+	width++;
+
+	while (width >= SPANSIZE)
+	{
+		iz += izstep;
+		uz += uzstep;
+		vz += vzstep;
+
+		double endz = 1.f/iz;
+		double endu = uz*endz;
+		double endv = vz*endz;
+		UINT32 stepu = (UINT32)((endu - startu) * INVSPAN);
+		UINT32 stepv = (UINT32)((endv - startv) * INVSPAN);
+		u = (UINT32)(startu) + viewx;
+		v = (UINT32)(startv) + viewy;
+
+		for (i = SPANSIZE-1; i >= 0; i--)
+		{
+			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+			*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+			dest++;
+			u += stepu;
+			v += stepv;
+		}
+		startu = endu;
+		startv = endv;
+		width -= SPANSIZE;
+	}
+	if (width > 0)
+	{
+		if (width == 1)
+		{
+			u = (UINT32)(startu);
+			v = (UINT32)(startv);
+			colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+			*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+		}
+		else
+		{
+			double left = width;
+			iz += ds_sz.x * left;
+			uz += ds_su.x * left;
+			vz += ds_sv.x * left;
+
+			double endz = 1.f/iz;
+			double endu = uz*endz;
+			double endv = vz*endz;
+			left = 1.f/left;
+			UINT32 stepu = (UINT32)((endu - startu) * left);
+			UINT32 stepv = (UINT32)((endv - startv) * left);
+			u = (UINT32)(startu) + viewx;
+			v = (UINT32)(startv) + viewy;
+
+			for (; width != 0; width--)
+			{
+				colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
+				*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
+				dest++;
+				u += stepu;
+				v += stepv;
+			}
+		}
+	}
+#endif
+}
 #endif // ESLOPE
 
 /**	\brief The R_DrawSplat_8 function
diff --git a/src/r_plane.c b/src/r_plane.c
index c39be11a93a6d80e3653441b4173ec20c9488656..b0768539b26f361f32a06e3fad2d0b299fc6efff 100644
--- a/src/r_plane.c
+++ b/src/r_plane.c
@@ -990,7 +990,10 @@ void R_DrawSinglePlane(visplane_t *pl)
 		ds_sv.z *= SFMULT;
 #undef SFMULT
 
-		spanfunc = R_DrawTiltedSpan_8;
+		if (spanfunc == R_DrawTranslucentSpan_8)
+			spanfunc = R_DrawTiltedTranslucentSpan_8;
+		else
+			spanfunc = R_DrawTiltedSpan_8;
 
 		planezlight = scalelight[light];
 	} else