diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h
index 57c9d99ab17910c4dbea55c6e199df8a8b3394a4..8cbb53de6d0303b85ea713ba8da5934fca3b40dc 100644
--- a/src/hardware/hw_drv.h
+++ b/src/hardware/hw_drv.h
@@ -76,6 +76,7 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boo
 EXPORT void HWRAPI(InitCustomShaders) (void);
 
 EXPORT void HWRAPI(LevelSurfaceLighting) (UINT8 lightlevel, FConvertedColormap *pColormap, UINT8 opacity);
+EXPORT void HWRAPI(ModelLighting) (float red, float green, float blue, float opacity);
 
 // ==========================================================================
 //                                      HWR DRIVER OBJECT, FOR CLIENT PROGRAM
@@ -128,7 +129,8 @@ struct hwdriver_s
 	InitCustomShaders   pfnInitCustomShaders;
 	
 	LevelSurfaceLighting pfnLevelSurfaceLighting;
-	//don't forget about i_video.c and hw_sym.c and change it to xmacros or get rid of it or whatever
+	ModelLighting        pfnModelLighting;
+	//don't forget about sdl/i_video.c and sdl/hwsym_sdl.c and change it to xmacros or get rid of it or whatever because it's driving me nuts
 };
 
 extern struct hwdriver_s hwdriver;
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 147e7449d868a504cade73cb4d6f06cf71363672..7be0e0c0bc17d761e59e3e158a2b4cc337c3662f 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -239,6 +239,27 @@ void HWR_Lighting(UINT8 lightlevel, extracolormap_t *colormap, UINT8 opacity, hw
 	HWD.pfnLevelSurfaceLighting(lightlevel, &cc, opacity);
 }
 
+void HWR_ModelLighting(UINT8 lightlevel, extracolormap_t *colormap, UINT8 opacity) {
+	FConvertedColormap cc = ConvertColormap(colormap);
+	//crappy color mixing based on colormaps (treats both low intensity colormaps and strong white colormaps as white light)
+	float red   = cc.tint_color.s.red/255.0f;
+	float green = cc.tint_color.s.green/255.0f;
+	float blue  = cc.tint_color.s.blue/255.0f;
+	float intensity  = cc.tint_color.s.alpha/255.0f;
+	if(intensity > 1.0f) intensity = 1.0f;
+	float a = 1.0f - intensity;
+	float fade_red   = cc.fade_color.s.red/255.0f;
+	float fade_green = cc.fade_color.s.green/255.0f;
+	float fade_blue  = cc.fade_color.s.blue/255.0f;
+	float l = lightlevel/255.0f;
+	float il = 1.0f-l;
+	float mixred   = l * (a * 1.0f + intensity * red)   + il * fade_red;
+	float mixgreen = l * (a * 0.9f + intensity * green) + il * fade_green;
+	float mixblue  = l * (a * 0.8f + intensity * blue)  + il * fade_blue;
+	HWD.pfnSetShader(HWD_SHADER_MODEL);
+	HWD.pfnModelLighting(mixred, mixgreen, mixblue, opacity/255.0f);
+}
+
 UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
 {
 	RGBA_t realcolor, surfcolor;
diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h
index 7ef99feaae8856d48a0909288a20053a6e0bba14..9111565b3aa3aacef1cdc4bfeecd30e5803ff096 100644
--- a/src/hardware/hw_main.h
+++ b/src/hardware/hw_main.h
@@ -66,7 +66,7 @@ void HWR_DrawScreenFinalTexture(int width, int height);
 
 // This stuff is put here so MD2's can use them
 void HWR_Lighting(UINT8 lightlevel, extracolormap_t *colormap, UINT8 opacity, hwdshader_t shader);
-//void HWR_Lighting(const FSurfaceInfo *pSurf, extracolormap_t *colormap);
+void HWR_ModelLighting(UINT8 lightlevel, extracolormap_t *colormap, UINT8 opacity);
 UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
 
 void HWR_ReadShaders(UINT16 wadnum, boolean PK3);
diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index 2729640ff10cd8ae0c644a9acd4b20073bc47d35..d1cf450a22082e372113c6c5ae826330a69eaa0e 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -1227,18 +1227,24 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
 		if (spr->mobj->flags2 & MF2_SHADOW) {
 			opacity = 0x40;
 			Surf.BlendMode = HWD_BLEND_TRANSLUCENT;
-			Surf.TintMode = HWD_TINT_ONLY_ALPHA;
+			Surf.TintMode = HWD_TINT_INTERPOLATE;
+			Surf.PolyFlags = 0;
 		} else if (spr->mobj->frame & FF_TRANSMASK) {
 			opacity = trans2alpha[(spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT];
 			Surf.BlendMode = HWD_BLEND_TRANSLUCENT;
-			Surf.TintMode = HWD_TINT_ONLY_ALPHA;
+			Surf.TintMode = HWD_TINT_INTERPOLATE;
+			Surf.PolyFlags = 0;
 		} else {
 			opacity = 0xFF;
 			Surf.BlendMode = HWD_BLEND_NONE;
-			Surf.TintMode = HWD_TINT_NONE;
+			Surf.TintMode = HWD_TINT_INTERPOLATE; //doesn't work well with modellighting
+			Surf.PolyFlags = PF_Occlude;
 		}
 
-		HWR_Lighting(lightlevel, colormap, opacity, HWD_SHADER_MODEL);
+		if(cv_grmodellighting.value)
+			HWR_ModelLighting(lightlevel, colormap, opacity);
+		else
+			HWR_Lighting(lightlevel, colormap, opacity, HWD_SHADER_MODEL); //doesn't work well with modellighting
 	}
 
 	// Look at HWR_ProjectSprite for more
@@ -1508,7 +1514,6 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
 		p.mirror = atransform.mirror; // from Kart
 #endif
 
-		HWD.pfnSetShader(HWD_SHADER_MODEL);
 		HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf);
 	}
 
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index f61a08b5b3a89c04e0d45e7e72997f5003c3b837..4a02946010402a7dc989ede1fa977ba2048ed94b 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -1905,6 +1905,46 @@ EXPORT void HWRAPI(LevelSurfaceLighting) (UINT8 lightlevel, FConvertedColormap *
 	}
 }
 
+EXPORT void HWRAPI(ModelLighting) (float red, float green, float blue, float opacity)
+{
+#ifdef GL_LIGHT_MODEL_AMBIENT
+	if (model_lighting && (!gl_shadersenabled)) // doesn't work with shaders anyway
+	{
+		// Because otherwise, scaling the screen negatively vertically breaks the lighting
+		GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f};
+
+		GLfloat ambient[4];
+		GLfloat diffuse[4];
+		
+		SetTintState(HWD_TINT_MULTIPLY); //TODO: doesn't work well with HWD_TINT_INTERPOLATE, rewrite as a shader
+
+		ambient[0] = (GLfloat) red;
+		ambient[1] = (GLfloat) green;
+		ambient[2] = (GLfloat) blue;
+		ambient[3] = (GLfloat) opacity;
+
+		if (ambient[0] > 0.75f)
+			ambient[0] = 0.75f;
+		if (ambient[1] > 0.75f)
+			ambient[1] = 0.75f;
+		if (ambient[2] > 0.75f)
+			ambient[2] = 0.75f;
+
+		diffuse[0] = (GLfloat) red;
+		diffuse[1] = (GLfloat) green;
+		diffuse[2] = (GLfloat) blue;
+		diffuse[3] = (GLfloat) opacity;
+
+		pglLightfv(GL_LIGHT0, GL_POSITION, LightPos);
+		pglShadeModel(GL_SMOOTH);
+
+		pglEnable(GL_LIGHTING);
+		pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
+		pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
+	}
+#endif
+}
+
 // -----------------+
 // DrawPolygon      : Render a polygon, (no longer) set the texture, set render mode
 // -----------------+
@@ -2553,11 +2593,6 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
 
 static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *pSurf)
 {
-	//GLRGBAFloat tint = FLOAT_RGBA(pSurf->TintColor);
-	//GLRGBAFloat fade = FLOAT_RGBA(pSurf->FadeColor);
-
-	GLRGBAFloat poly;
-
 	float pol = 0.0f;
 	float scalex, scaley, scalez;
 
@@ -2565,12 +2600,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
 
 	int i;
 
-	// Because otherwise, scaling the screen negatively vertically breaks the lighting
-	GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f};
-#ifdef GL_LIGHT_MODEL_AMBIENT
-	GLfloat ambient[4];
-	GLfloat diffuse[4];
-#endif
+	SetBlendState(pSurf->BlendMode);
+	SetStateFromPolyFlags(pSurf->PolyFlags);
 
 	// Affect input model scaling
 	scale *= 0.5f;
@@ -2590,69 +2621,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
 		if (pol < 0.0f)
 			pol = 0.0f;
 	}
-	
-	/*
-	poly.red = tint.red;
-	poly.green = tint.green;
-	poly.blue = tint.blue;
-	poly.alpha = byte2float[pSurf->Opacity];
-	*/
-	
-	poly.red = 255;
-	poly.green = 255;
-	poly.blue = 244;
-	poly.alpha = 255;
-
-#ifdef GL_LIGHT_MODEL_AMBIENT
-	if (model_lighting && (!gl_shadersenabled)) // doesn't work with shaders anyway
-	{
-		ambient[0] = poly.red;
-		ambient[1] = poly.green;
-		ambient[2] = poly.blue;
-		ambient[3] = poly.alpha;
-
-		diffuse[0] = poly.red;
-		diffuse[1] = poly.green;
-		diffuse[2] = poly.blue;
-		diffuse[3] = poly.alpha;
-
-		if (ambient[0] > 0.75f)
-			ambient[0] = 0.75f;
-		if (ambient[1] > 0.75f)
-			ambient[1] = 0.75f;
-		if (ambient[2] > 0.75f)
-			ambient[2] = 0.75f;
-
-		pglLightfv(GL_LIGHT0, GL_POSITION, LightPos);
-		pglShadeModel(GL_SMOOTH);
-
-		pglEnable(GL_LIGHTING);
-		pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
-		pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
-	}
-#endif
-	else
-		pglColor4fv((GLfloat*)&poly);
-
-    if(poly.alpha < 1) {
-        SetRenderState(HWD_TINT_MULTIPLY, HWD_BLEND_TRANSLUCENT, 0);
-    } else {
-        SetRenderState(HWD_TINT_MULTIPLY, HWD_BLEND_MASKED, PF_Occlude);
-    }
-
-	/*
-	tint.red   = byte2float[pSurf->TintColor.s.red];
-	tint.green = byte2float[pSurf->TintColor.s.green];
-	tint.blue  = byte2float[pSurf->TintColor.s.blue];
-	tint.alpha = byte2float[pSurf->TintColor.s.alpha];
-
-	fade.red   = byte2float[pSurf->FadeColor.s.red];
-	fade.green = byte2float[pSurf->FadeColor.s.green];
-	fade.blue  = byte2float[pSurf->FadeColor.s.blue];
-	fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
-
-	Shader_Load(pSurf, poly.alpha, &tint, &fade);
-	*/
 
 	pglEnable(GL_CULL_FACE);
 	pglEnable(GL_NORMALIZE);
diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c
index f134437601cd32f442aa6b64787fcd72c5cbdde9..2ceb1a17a963b67ad488deb537c60c916db3849c 100644
--- a/src/sdl/hwsym_sdl.c
+++ b/src/sdl/hwsym_sdl.c
@@ -112,6 +112,7 @@ void *hwSym(const char *funcName,void *handle)
 	GETFUNC(InitCustomShaders);
 
 	GETFUNC(LevelSurfaceLighting);
+	GETFUNC(ModelLighting);
 	//killme
 
 #else //HWRENDER
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 6d198062f583db553877e1e1a69b281c596e0e2a..71a874298beecc772019482c1f93cef05490a423 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -1808,6 +1808,7 @@ void I_StartupHardwareGraphics(void)
 		HWD.pfnInitCustomShaders= hwSym("InitCustomShaders",NULL);
 		
 		HWD.pfnLevelSurfaceLighting=hwSym("LevelSurfaceLighting",NULL);
+		HWD.pfnModelLighting    = hwSym("ModelLighting",NULL);
 
 		if (!HWD.pfnInit()) // let load the OpenGL library
 		{