diff --git a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp
index 7368fa121..6f9af51fc 100644
--- a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp
+++ b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp
@@ -260,7 +260,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
 		SetStencilBlock(x / 8 + y / 8 * stencilPitch);
 
 		SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded;
-		if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
+		if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector)
 		{
 			covered = covered && StencilIsSingleValue();
 		}
@@ -287,7 +287,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
 void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
 {
 	SSAIfBlock branch_stenciltest;
-	if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
+	if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector)
 	{
 		branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue);
 	}
@@ -325,7 +325,7 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
 				varying[i] = stack_varying[i].load();
 			loopx.loop_block(ix < SSAInt(q), q);
 			{
-				if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector)
+				if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::DrawShadedSubsector || variant == TriDrawVariant::FillSubsector)
 				{
 					SSAIfBlock branch;
 					branch.if_block(subsectorbuffer[ix].load(true) >= subsectorDepth);
@@ -353,7 +353,7 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
 		loopy.end_block();
 	}
 
-	if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
+	if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector)
 	{
 		branch_stenciltest.end_block();
 	}
@@ -404,7 +404,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
 			SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (cliptop <= y + iy) && (clipbottom > y + iy);
 			SSABool covered = CX1 > SSAInt(0) && CX2 > SSAInt(0) && CX3 > SSAInt(0) && visible;
 
-			if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector)
+			if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::DrawShadedSubsector || variant == TriDrawVariant::FillSubsector)
 			{
 				covered = covered && subsectorbuffer[ix].load(true) >= subsectorDepth;
 			}
@@ -474,13 +474,13 @@ void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbu
 
 		if (truecolor)
 		{
-			SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true);
-			SSAInt fg_alpha = fg[3];
-			fg = (fg * currentlight) >> 8;
-			fg.insert(3, fg_alpha);
-
 			if (variant == TriDrawVariant::DrawMasked || variant == TriDrawVariant::DrawSubsector)
 			{
+				SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true);
+				SSAInt fg_alpha = fg[3];
+				fg = (fg * currentlight) >> 8;
+				fg.insert(3, fg_alpha);
+
 				SSAIfBlock branch_transparency;
 				branch_transparency.if_block(fg_alpha > SSAInt(127));
 				{
@@ -490,8 +490,22 @@ void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbu
 				}
 				branch_transparency.end_block();
 			}
+			else if (variant == TriDrawVariant::DrawShadedSubsector)
+			{
+				SSAInt alpha = texturePixels[uvoffset * 4].load(true).zext_int();
+				alpha = alpha + (alpha >> 7); // // 255 -> 256
+				SSAInt inv_alpha = 256 - alpha;
+
+				SSAVec4i bgcolor = buffer.load_vec4ub(false);
+				buffer.store_vec4ub(blend_add(shade_bgra_simple(SSAVec4i::unpack(solidcolor), currentlight), bgcolor, alpha, inv_alpha));
+			}
 			else
 			{
+				SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true);
+				SSAInt fg_alpha = fg[3];
+				fg = (fg * currentlight) >> 8;
+				fg.insert(3, fg_alpha);
+
 				buffer.store_vec4ub(fg);
 				subsectorbuffer.store(subsectorDepth);
 			}
diff --git a/src/r_compiler/llvmdrawers.cpp b/src/r_compiler/llvmdrawers.cpp
index e7b9f6e5c..458d90d1a 100644
--- a/src/r_compiler/llvmdrawers.cpp
+++ b/src/r_compiler/llvmdrawers.cpp
@@ -190,6 +190,8 @@ LLVMDrawersImpl::LLVMDrawersImpl()
 	CodegenDrawTriangle("TriDraw32", TriDrawVariant::Draw, true);
 	CodegenDrawTriangle("TriDrawSubsector8", TriDrawVariant::DrawSubsector, false);
 	CodegenDrawTriangle("TriDrawSubsector32", TriDrawVariant::DrawSubsector, true);
+	CodegenDrawTriangle("TriDrawShadedSubsector8", TriDrawVariant::DrawShadedSubsector, false);
+	CodegenDrawTriangle("TriDrawShadedSubsector32", TriDrawVariant::DrawShadedSubsector, true);
 	CodegenDrawTriangle("TriFillSubsector8", TriDrawVariant::FillSubsector, false);
 	CodegenDrawTriangle("TriFillSubsector32", TriDrawVariant::FillSubsector, true);
 	CodegenDrawTriangle("TriFill8", TriDrawVariant::Fill, false);
@@ -264,6 +266,8 @@ LLVMDrawersImpl::LLVMDrawersImpl()
 	TriDraw32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32");
 	TriDrawSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8");
 	TriDrawSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32");
+	TriDrawShadedSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector8");
+	TriDrawShadedSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector32");
 	TriFillSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8");
 	TriFillSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32");
 	TriFill8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8");
diff --git a/src/r_compiler/llvmdrawers.h b/src/r_compiler/llvmdrawers.h
index e7a34b962..9c3a3e45f 100644
--- a/src/r_compiler/llvmdrawers.h
+++ b/src/r_compiler/llvmdrawers.h
@@ -266,6 +266,7 @@ enum class TriDrawVariant
 	DrawMasked,
 	Fill,
 	DrawSubsector,
+	DrawShadedSubsector,
 	FillSubsector,
 	Stencil,
 };
@@ -349,6 +350,8 @@ public:
 	void(*TriDraw32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
 	void(*TriDrawSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
 	void(*TriDrawSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
+	void(*TriDrawShadedSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
+	void(*TriDrawShadedSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
 	void(*TriFillSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
 	void(*TriFillSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
 	void(*TriFill8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
diff --git a/src/r_poly_decal.cpp b/src/r_poly_decal.cpp
index af9c53a89..011ce83e4 100644
--- a/src/r_poly_decal.cpp
+++ b/src/r_poly_decal.cpp
@@ -155,5 +155,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co
 	args.stenciltestvalue = 0;
 	args.stencilwritevalue = 1;
 	args.SetTexture(tex);
-	PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector);
+	args.solidcolor = decal->AlphaColor;
+	//mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
+	PolyTriangleDrawer::draw(args, TriDrawVariant::DrawShadedSubsector);
 }
diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp
index 6426bae4e..64611376b 100644
--- a/src/r_poly_triangle.cpp
+++ b/src/r_poly_triangle.cpp
@@ -62,6 +62,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
 	case TriDrawVariant::Draw: drawfunc = r_swtruecolor ? llvm->TriDraw32: llvm->TriDraw8; break;
 	case TriDrawVariant::Fill: drawfunc = r_swtruecolor ? llvm->TriFill32 : llvm->TriFill8; break;
 	case TriDrawVariant::DrawSubsector: drawfunc = r_swtruecolor ? llvm->TriDrawSubsector32 : llvm->TriDrawSubsector8; break;
+	case TriDrawVariant::DrawShadedSubsector: drawfunc = r_swtruecolor ? llvm->TriDrawShadedSubsector32 : llvm->TriDrawShadedSubsector8; break;
 	case TriDrawVariant::FillSubsector: drawfunc = r_swtruecolor ? llvm->TriFillSubsector32 : llvm->TriFillSubsector8; break;
 	case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break;
 	}
@@ -72,6 +73,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
 	case TriDrawVariant::Draw: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break;
 	case TriDrawVariant::FillSubsector:
 	case TriDrawVariant::Fill: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break;
+	case TriDrawVariant::DrawShadedSubsector:
 	case TriDrawVariant::DrawSubsector: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break;
 	case TriDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break;
 	}