diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 58c94b31ed6777c823c7d1951cfea98f5d940327..9ff4039cf3f5440d12fab04907ffc0154d4b5f86 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -5021,6 +5021,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
 #ifdef ROTSPRITE
 	patch_t *rotsprite = NULL;
 	INT32 rollangle = 0;
+	angle_t spriterotangle = 0;
 #endif
 
 	if (!thing)
@@ -5168,10 +5169,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
 	spr_topoffset = spritecachedinfo[lumpoff].topoffset;
 
 #ifdef ROTSPRITE
-	if (thing->rollangle
+	spriterotangle = R_SpriteRotationAngle(thing);
+
+	if (spriterotangle != 0
 	&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
 	{
-		rollangle = R_GetRollAngle(thing->rollangle);
+		rollangle = R_GetRollAngle(spriterotangle);
 		rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
 
 		if (rotsprite != NULL)
diff --git a/src/r_patch.h b/src/r_patch.h
index 26c28e1f9c4bbfb2a1b46b55e8fd737a0a0b3804..cebe6763a7fb7b2c423d7fd44ece2c560f4dba59 100644
--- a/src/r_patch.h
+++ b/src/r_patch.h
@@ -38,6 +38,7 @@ patch_t *Patch_GetRotatedSprite(
 	size_t frame, size_t spriteangle,
 	boolean flip, boolean adjustfeet,
 	void *info, INT32 rotationangle);
+angle_t R_SpriteRotationAngle(mobj_t *mobj);
 INT32 R_GetRollAngle(angle_t rollangle);
 #endif
 
diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c
index b24e065ba6cfb172ce926805e4557c11b693a00e..106bf75bac293444f0c1fb6b959374241c352a55 100644
--- a/src/r_patchrotation.c
+++ b/src/r_patchrotation.c
@@ -13,11 +13,29 @@
 #include "r_things.h" // FEETADJUST
 #include "z_zone.h"
 #include "w_wad.h"
+#include "r_main.h" // R_PointToAngle
 
 #ifdef ROTSPRITE
 fixed_t rollcosang[ROTANGLES];
 fixed_t rollsinang[ROTANGLES];
 
+//
+// R_SpriteRotationAngle
+//
+// Gets the rollangle for the input object.
+//
+angle_t R_SpriteRotationAngle(mobj_t *mobj)
+{
+	angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y);
+
+	fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT);
+	fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT);
+
+	angle_t rollOrPitch = FixedMul(mobj->pitch, pitchMul) + FixedMul(mobj->roll, rollMul);
+
+	return (rollOrPitch + mobj->rollangle);
+}
+
 INT32 R_GetRollAngle(angle_t rollangle)
 {
 	INT32 ra = AngleFixed(rollangle)>>FRACBITS;
diff --git a/src/r_things.c b/src/r_things.c
index e689e284a96b1e90a9bc68b5d0260f4061990516..2f7d4c1b09a514bfe5dbcc4d34caaec1e4cc901a 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1479,6 +1479,7 @@ static void R_ProjectSprite(mobj_t *thing)
 #ifdef ROTSPRITE
 	patch_t *rotsprite = NULL;
 	INT32 rollangle = 0;
+	angle_t spriterotangle = 0;
 #endif
 
 	// transform the origin point
@@ -1609,17 +1610,19 @@ static void R_ProjectSprite(mobj_t *thing)
 	patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
 
 #ifdef ROTSPRITE
-	if (thing->rollangle
+	spriterotangle = R_SpriteRotationAngle(thing);
+
+	if (spriterotangle != 0
 	&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
 	{
 		if (papersprite && ang >= ANGLE_180)
 		{
 			// Makes Software act much more sane like OpenGL
-			rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
+			rollangle = R_GetRollAngle(InvAngle(spriterotangle));
 		}
 		else
 		{
-			rollangle = R_GetRollAngle(thing->rollangle);
+			rollangle = R_GetRollAngle(spriterotangle);
 		}
 
 		rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);