Index: glprogs/oldStage.fs
===================================================================
--- glprogs/oldStage.fs	(revision 9322)
+++ glprogs/oldStage.fs	(working copy)
@@ -2,6 +2,7 @@
 
 uniform float u_screenTex;
 uniform sampler2D u_tex0;
+uniform float u_offsetRawZ;
 
 in vec4 var_TexCoord0;
 in vec4 var_Color;
@@ -8,6 +9,21 @@
 
 out vec4 FragColor;
 
+#pragma tdm_include "tdm_transform.glsl"
+float depthToZ(float depth) {
+	float clipZ = 2.0 * depth - 1.0;
+	float A = u_projectionMatrix[2].z;
+	float B = u_projectionMatrix[3].z;
+	return B / (A + clipZ);
+}
+float zToDepth(float z) {
+	float A = u_projectionMatrix[2].z;
+	float B = u_projectionMatrix[3].z;
+	float clipZ = (B / z) - A;
+    return (clipZ + 1.0) * 0.5;
+}
+
+
 void main() {
 	vec4 tex;
 	if (u_screenTex == 1.0) {
@@ -18,4 +34,12 @@
 	} else
 		tex = textureProj(u_tex0, var_TexCoord0);
 	FragColor = tex*var_Color;
+
+    if (u_offsetRawZ != 0.0) {
+        float newDepth = zToDepth(depthToZ(gl_FragCoord.z) + u_offsetRawZ);
+        newDepth = min(newDepth, gl_FragCoord.z);
+        gl_FragDepth = newDepth;
+    }
+    else
+        gl_FragDepth = gl_FragCoord.z;
 }
\ No newline at end of file
Index: glprogs/stages/depth/depth.frag.glsl
===================================================================
--- glprogs/stages/depth/depth.frag.glsl	(revision 9322)
+++ glprogs/stages/depth/depth.frag.glsl	(working copy)
@@ -25,6 +25,23 @@
 }
 #endif
 
+uniform ViewParamsBlock {
+	uniform mat4 u_projectionMatrix;
+};
+float depthToZ(float depth) {
+	float clipZ = 2.0 * depth - 1.0;
+	float A = u_projectionMatrix[2].z;
+	float B = u_projectionMatrix[3].z;
+	return B / (A + clipZ);
+}
+float zToDepth(float z) {
+	float A = u_projectionMatrix[2].z;
+	float B = u_projectionMatrix[3].z;
+	float clipZ = (B / z) - A;
+    return (clipZ + 1.0) * 0.5;
+}
+
+
 void main() {
 	if (clipPlaneDist < 0.0)
 		discard;
@@ -33,6 +50,14 @@
 	if (gl_FragCoord.x < scissor.x || gl_FragCoord.y < scissor.y || gl_FragCoord.x >= scissor.x + scissor.z || gl_FragCoord.y >= scissor.y + scissor.w)
 		discard;
 	
+    if (params[var_DrawId].offsetRawZ != 0.0) {
+        float newDepth = zToDepth(depthToZ(gl_FragCoord.z) + params[var_DrawId].offsetRawZ);
+        newDepth = min(newDepth, gl_FragCoord.z);
+        gl_FragDepth = newDepth;
+    }
+    else
+        gl_FragDepth = gl_FragCoord.z;
+
 	if (params[var_DrawId].alphaTest < 0) {
 		FragColor = params[var_DrawId].color;
 	}
Index: glprogs/stages/depth/depth.params.glsl
===================================================================
--- glprogs/stages/depth/depth.params.glsl	(revision 9322)
+++ glprogs/stages/depth/depth.params.glsl	(working copy)
@@ -7,7 +7,7 @@
 	uvec4 scissor;
 	uvec2 texture;
 	float alphaTest;
-	float padding;
+	float offsetRawZ;
 };
 
 layout (std140) uniform PerDrawCallParamsBlock {
Index: glprogs/stages/interaction/interaction.ambient.fs.glsl
===================================================================
--- glprogs/stages/interaction/interaction.ambient.fs.glsl	(revision 9322)
+++ glprogs/stages/interaction/interaction.ambient.fs.glsl	(working copy)
@@ -136,4 +136,5 @@
 	}
 
 	FragColor = light;
+    gl_FragDepth = gl_FragCoord.z;
 }
Index: glprogs/stages/interaction/interaction.stencil.fs.glsl
===================================================================
--- glprogs/stages/interaction/interaction.stencil.fs.glsl	(revision 9322)
+++ glprogs/stages/interaction/interaction.stencil.fs.glsl	(working copy)
@@ -106,4 +106,5 @@
 	if (u_shadows && u_softShadowsQuality > 0)
 		StencilSoftShadow();
 	FragColor.a = 1.0;
+    gl_FragDepth = gl_FragCoord.z;
 }
Index: renderer/backend/DepthStage.cpp
===================================================================
--- renderer/backend/DepthStage.cpp	(revision 9322)
+++ renderer/backend/DepthStage.cpp	(working copy)
@@ -66,7 +66,7 @@
 	uint32_t scissor[4];
 	uint64_t textureHandle;
 	float alphaTest;
-	float padding;
+	float offsetRawZ;
 };
 
 DepthStage::DepthStage( DrawBatchExecutor* drawBatchExecutor )
@@ -288,6 +288,12 @@
 	CalcScissorParam( params.scissor, surf->scissorRect );
 	params.alphaTest = -1.f;
 
+	params.offsetRawZ = 0.0f;
+	const idMaterial *shader = surf->material;
+	if ( shader->TestMaterialFlag( MF_POLYGONOFFSET ) ) {
+		params.offsetRawZ = shader->GetPolygonOffset() * r_offsetRawZ.GetFloat();
+	}
+
 	if ( surf->material->GetSort() == SS_SUBVIEW ) {
 		// subviews will just down-modulate the color buffer by overbright
 		params.color[0] = params.color[1] = params.color[2] = 1.0f / backEnd.overBright;
Index: renderer/draw_common.cpp
===================================================================
--- renderer/draw_common.cpp	(revision 9322)
+++ renderer/draw_common.cpp	(working copy)
@@ -370,6 +370,12 @@
 	default:
 		programManager->oldStageShader->Activate();
 		OldStageUniforms *oldStageUniforms = programManager->oldStageShader->GetUniformGroup<OldStageUniforms>();
+
+		oldStageUniforms->offsetRawZ.Set(0.0f);
+		if ( pStage->privatePolygonOffset || surf->material->TestMaterialFlag( MF_POLYGONOFFSET ) ) {
+			oldStageUniforms->offsetRawZ.Set(r_offsetRawZ.GetFloat());
+		}
+
 		switch ( pStage->vertexColor )	 {
 		case SVC_IGNORE:
 			oldStageUniforms->colorMul.Set( zero );
Index: renderer/glsl.h
===================================================================
--- renderer/glsl.h	(revision 9322)
+++ renderer/glsl.h	(working copy)
@@ -202,6 +202,7 @@
 	DEFINE_UNIFORM( float, screenTex );
 	DEFINE_UNIFORM( vec4, colorMul );
 	DEFINE_UNIFORM( vec4, colorAdd );
+	DEFINE_UNIFORM( float, offsetRawZ );
 };
 
 GLSLProgram* GLSL_LoadMaterialStageProgram(const char *name);
Index: renderer/RenderSystem_init.cpp
===================================================================
--- renderer/RenderSystem_init.cpp	(revision 9323)
+++ renderer/RenderSystem_init.cpp	(working copy)
@@ -122,8 +122,9 @@
 idCVar r_useFrustumFarDistance( "r_useFrustumFarDistance", "0", CVAR_RENDERER | CVAR_FLOAT, "if != 0 force the view frustum far distance to this distance" );
 idCVar r_logFile( "r_logFile", "0", CVAR_RENDERER | CVAR_INTEGER, "number of frames to emit GL logs" );
 idCVar r_clear( "r_clear", "2", CVAR_RENDERER | CVAR_ARCHIVE, "force screen clear every frame, 1 = purple, 2 = black, 'r g b' = custom" );
-idCVar r_offsetFactor( "r_offsetfactor", "-2", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "polygon offset parameter" ); // #4079
-idCVar r_offsetUnits( "r_offsetunits", "-0.1", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "polygon offset parameter" ); // #4079
+idCVar r_offsetFactor( "r_offsetfactor", "0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "glPolygonOffset 'factor' parameter" ); // #4079
+idCVar r_offsetUnits( "r_offsetunits", "-1", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "glPolygonOffset 'units' parameter" ); // #4079
+idCVar r_offsetRawZ( "r_offsetrawz", "-0.1", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "offset every fragment by X doom units away from eye" );
 idCVar r_shadowPolygonOffset( "r_shadowPolygonOffset", "-1", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "bias value added to depth test for stencil shadow drawing" );
 idCVar r_shadowPolygonFactor( "r_shadowPolygonFactor", "0", CVAR_RENDERER | CVAR_FLOAT | CVAR_ARCHIVE, "scale value for stencil shadow drawing" );
 idCVar r_frontBuffer( "r_frontBuffer", "0", CVAR_RENDERER | CVAR_BOOL, "draw to front buffer for debugging" );
Index: renderer/tr_local.h
===================================================================
--- renderer/tr_local.h	(revision 9322)
+++ renderer/tr_local.h	(working copy)
@@ -921,6 +921,7 @@
 extern idCVarInt r_swapInterval;			// changes wglSwapIntarval
 extern idCVar r_offsetFactor;			// polygon offset parameter
 extern idCVar r_offsetUnits;			// polygon offset parameter
+extern idCVar r_offsetRawZ;
 extern idCVar r_singleTriangle;			// only draw a single triangle per primitive
 extern idCVar r_logFile;				// number of frames to emit GL logs
 extern idCVar r_clear;					// force screen clear every frame
