diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 919d35b53fafbd5b2e73dd41b0b8719ceffdf7d8..374fbe9690902b38fd55b92c2332e4cf7cc7aef3 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -853,6 +853,7 @@ void D_RegisterClientCommands(void)
 	// screen.c
 	CV_RegisterVar(&cv_fullscreen);
 	CV_RegisterVar(&cv_renderview);
+	CV_RegisterVar(&cv_renderwalls);
 	CV_RegisterVar(&cv_renderer);
 	CV_RegisterVar(&cv_scr_depth);
 	CV_RegisterVar(&cv_scr_width);
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index dd633d6fc428aa3f2b96fafa0721f294ea23b64e..466c6653869fd887df25e2989e41fcbc42062d48 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -800,6 +800,9 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
 {
 	INT32 shader = SHADER_DEFAULT;
 
+	if (!cv_renderwalls.value)
+		return;
+
 	HWR_Lighting(pSurf, lightlevel, wallcolormap);
 
 	if (HWR_UseShader())
@@ -882,6 +885,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
 	FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y);
 	extracolormap_t *colormap = NULL;
 
+	if (!cv_renderwalls.value)
+		return;
+
 	realtop = top = wallVerts[3].y;
 	realbot = bot = wallVerts[0].y;
 	pegt = wallVerts[3].t;
@@ -6492,6 +6498,9 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 te
 {
 	static size_t allocedwalls = 0;
 
+	if (!cv_renderwalls.value)
+		return;
+
 	// Force realloc if buffer has been freed
 	if (!wallinfo)
 		allocedwalls = 0;
@@ -6520,6 +6529,9 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
 
 	INT32 shader = SHADER_DEFAULT;
 
+	if (!cv_renderwalls.value)
+		return;
+
 	// Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting
 	HWR_Lighting(pSurf, lightlevel, wallcolormap);
 
diff --git a/src/r_segs.c b/src/r_segs.c
index a8c85ec33bade941039e1c88fea53906d37a3ee7..be24be88625b8fd224af80ca746c85d5c7e0d9c9 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -87,6 +87,9 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
 {
 	INT32 topscreen, bottomscreen;
 
+	if (!cv_renderwalls.value)
+		return;
+
 	topscreen = sprtopscreen; // + spryscale*column->topdelta;  topdelta is 0 for the wall
 	bottomscreen = topscreen + spryscale * lengthcol;
 
@@ -315,6 +318,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
 	else
 		repeats = 1;
 
+	if (!cv_renderwalls.value)
+		return;
+
 	for (times = 0; times < repeats; times++)
 	{
 		if (times > 0)
@@ -858,6 +864,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
 		bottom_frac += bottom_step * (x1 - ds->x1);
 	}
 
+	if (!cv_renderwalls.value)
+		return;
+
 	// draw the columns
 	for (dc_x = x1; dc_x <= x2; dc_x++)
 	{
@@ -1347,7 +1356,8 @@ static void R_RenderSegLoop (void)
 #ifdef TIMING
 				ProfZeroTimer();
 #endif
-				colfunc();
+				if (cv_renderwalls.value)
+					colfunc();
 #ifdef TIMING
 				RDMSR(0x10,&mycount);
 				mytotal += mycount;      //64bit add
@@ -1403,7 +1413,8 @@ static void R_RenderSegLoop (void)
 						dc_texturemid = rw_toptexturemid;
 						dc_source = R_GetColumn(toptexture,texturecolumn);
 						dc_texheight = textureheight[toptexture]>>FRACBITS;
-						colfunc();
+						if (cv_renderwalls.value)
+							colfunc();
 						ceilingclip[rw_x] = (INT16)mid;
 					}
 					else if (!rw_ceilingmarked) // entirely off top of screen
@@ -1440,7 +1451,8 @@ static void R_RenderSegLoop (void)
 						dc_source = R_GetColumn(bottomtexture,
 							texturecolumn);
 						dc_texheight = textureheight[bottomtexture]>>FRACBITS;
-						colfunc();
+						if (cv_renderwalls.value)
+							colfunc();
 						floorclip[rw_x] = (INT16)mid;
 					}
 					else if (!rw_floormarked)  // entirely off bottom of screen
diff --git a/src/screen.c b/src/screen.c
index 770f1c8026aaf4fcb5dd9df97da55271f717b547..5576cc51491bb4e1e28180f3b935301dbeebfce0 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -68,6 +68,7 @@ consvar_t cv_scr_width = CVAR_INIT ("scr_width", "1280", CV_SAVE, CV_Unsigned, N
 consvar_t cv_scr_height = CVAR_INIT ("scr_height", "800", CV_SAVE, CV_Unsigned, NULL);
 consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL);
 consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL);
+consvar_t cv_renderwalls = CVAR_INIT ("renderwalls", "On", 0, CV_OnOff, NULL);
 
 CV_PossibleValue_t cv_renderer_t[] = {
 	{1, "Software"},
diff --git a/src/screen.h b/src/screen.h
index 67880e2b964dc16a7693d754a6646bd031f14c04..003a1032d7257ec3ee1035c4563d0c86776ff4be 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -189,7 +189,7 @@ extern CV_PossibleValue_t cv_renderer_t[];
 extern INT32 scr_bpp;
 extern UINT8 *scr_borderpatch; // patch used to fill the view borders
 
-extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen;
+extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderwalls, cv_renderer, cv_fullscreen;
 // wait for page flipping to end or not
 extern consvar_t cv_vidwait;