From c36a52953b9b3cdecf31a2203c7661654f4c0e21 Mon Sep 17 00:00:00 2001 From: eihrul Date: Wed, 30 Sep 2009 10:20:58 +0000 Subject: [PATCH] added support for more shadowmap2D PCF modes and provisional fetch4 PCF git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9260 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 106 ++++++++++++++++++++++++++++------------------------- r_shadow.c | 12 +++--- 2 files changed, 62 insertions(+), 56 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 83d0faaa..997b8842 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -448,9 +448,13 @@ static const char *builtinshaderstring = "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n" "// written by Forest 'LordHavoc' Hale\n" "#ifdef USESHADOWMAPRECT\n" -"#extension GL_ARB_texture_rectangle : enable\n" +"# extension GL_ARB_texture_rectangle : enable\n" "#endif\n" +"\n" "#ifdef USESHADOWMAP2D\n" +"# ifdef GL_EXT_gpu_shader4\n" +"# extension GL_EXT_gpu_shader4 : enable\n" +"# endif\n" "# ifdef HASTEXTUREGATHER\n" "# extension GL_ARB_texture_gather : enable\n" "# else\n" @@ -460,8 +464,9 @@ static const char *builtinshaderstring = "# endif\n" "# endif\n" "#endif\n" +"\n" "#ifdef USESHADOWMAPCUBE\n" -"#extension GL_EXT_gpu_shader4 : enable\n" +"# extension GL_EXT_gpu_shader4 : enable\n" "#endif\n" "\n" "// common definitions between vertex shader and fragment shader:\n" @@ -982,7 +987,7 @@ static const char *builtinshaderstring = " return vec3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma + vec3(offset * ShadowMap_Parameters.y, ShadowMap_Parameters.z);\n" "# else\n" "# ifdef USESHADOWMAPRECT \n" -" return vec3(textureCube(Texture_CubeProjection, dir.xyz).ra * ShadowMap_TextureScale.xy, ShadowMap_TextureScale.z + ShadowMap_TextureScale.w / max(max(adir.x, adir.y), adir.z));\n" +" return vec3(textureCube(Texture_CubeProjection, dir.xyz).ra * ShadowMap_TextureScale.xy, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n" "# else\n" " return vec3(textureCube(Texture_CubeProjection, dir.xyz).ra, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n" "# endif\n" @@ -1007,11 +1012,8 @@ static const char *builtinshaderstring = "# ifdef USESHADOWSAMPLER\n" "\n" "# ifdef USESHADOWMAPPCF\n" -" f = dot(vec4(0.25),\n" -" vec4(shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3(-0.4, 1.0, 0.0)).r,\n" -" shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3(-1.0, -0.4, 0.0)).r,\n" -" shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3( 0.4, -1.0, 0.0)).r,\n" -" shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3( 1.0, 0.4, 0.0)).r));\n" +"# define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + vec3(x, y, 0.0)).r\n" +" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n" "# else\n" " f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n" "# endif\n" @@ -1019,53 +1021,20 @@ static const char *builtinshaderstring = "# else\n" "\n" "# ifdef USESHADOWMAPPCF\n" -"# if defined(HASTEXTUREGATHER) || defined(HASTEXTURE4)\n" -" vec2 offset = fract(shadowmaptc.xy - 0.5);\n" -" vec4 group1 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0, -1.0))),\n" -" group2 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0, -1.0))),\n" -" group3 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0, 1.0))),\n" -" group4 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0, 1.0))),\n" -" cols = vec4(group1.ab, group2.ab) + vec4(group3.rg, group4.rg) +\n" -" mix(vec4(group1.rg, group2.rg), vec4(group3.ab, group4.ab), offset.y);\n" -" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n" -"# elif 1\n" +"# define texval(x, y) texture2DRect(Texture_ShadowMapRect, center + vec2(x, y)).r\n" +"# if 1\n" " vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n" -" vec4 row1 = step(shadowmaptc.z,\n" -" vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0, -1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 0.0, -1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0, -1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0, -1.0)).r)),\n" -" row2 = step(shadowmaptc.z,\n" -" vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0, 0.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0, 0.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0, 0.0)).r)),\n" -" row3 = step(shadowmaptc.z,\n" -" vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0, 1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 0.0, 1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0, 1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0, 1.0)).r)),\n" -" row4 = step(shadowmaptc.z,\n" -" vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0, 2.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 0.0, 2.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0, 2.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0, 2.0)).r)),\n" +" vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0))),\n" +" row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0))),\n" +" row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0))),\n" +" row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0))),\n" " cols = row2 + row3 + mix(row1, row4, offset.y);\n" " f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n" "# else\n" " vec2 offset = fract(shadowmaptc.xy);\n" -" vec3 row1 = step(shadowmaptc.z,\n" -" vec3(texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0, -1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 0.0, -1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0, -1.0)).r)),\n" -" row2 = step(shadowmaptc.z,\n" -" vec3(texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0, 0.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r,\n" -" texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0, 0.0)).r)),\n" -" row3 = step(shadowmaptc.z,\n" -" vec3(texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0, 1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 0.0, 1.0)).r,\n" -" texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0, 1.0)).r)),\n" +" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0))),\n" +" row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)))\n" +" row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0))),\n" " cols = row2 + mix(row1, row3, offset.y);\n" " f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n" "# endif\n" @@ -1083,10 +1052,47 @@ static const char *builtinshaderstring = "{\n" " vec3 shadowmaptc = GetShadowMapTC2D(dir);\n" " float f;\n" +"\n" "# ifdef USESHADOWSAMPLER\n" +"# ifdef USESHADOWMAPPCF\n" +"# ifdef GL_EXT_gpu_shader4\n" +"# define texval(x, y) shadow2DOffset(Texture_ShadowMap2D, shadowmaptc, ivec2(x, y)).r\n" +"# else\n" +"# define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy + vec2(x, y)*ShadowMap_TextureScale.xy, shadowmaptc.z)).r \n" +"# endif\n" +" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n" +"# else\n" " f = shadow2D(Texture_ShadowMap2D, shadowmaptc).r;\n" +"# endif\n" "# else\n" +"# ifdef USESHADOWMAPPCF\n" +"# if defined(HASTEXTUREGATHER) || defined(HASTEXTURE4)\n" +" vec2 center = shadowmaptc.xy*ShadowMap_Texture_Scale.zw, offset = fract(center - 0.5);\n" +" vec4 group1 = step(shadowmaptc.z, textureGather(Texture_ShadowMap2D, (center + vec2(-1.0, -1.0))*ShadowMap_TextureScale.xy)),\n" +" group2 = step(shadowmaptc.z, textureGather(Texture_ShadowMap2D, (center + vec2( 1.0, -1.0))*ShadowMap_TextureScale.xy)),\n" +" group3 = step(shadowmaptc.z, textureGather(Texture_ShadowMap2D, (center + vec2(-1.0, 1.0))*ShadowMap_TextureScale.xy)),\n" +" group4 = step(shadowmaptc.z, textureGather(Texture_ShadowMap2D, (center + vec2( 1.0, 1.0))*ShadowMap_TextureScale.xy)),\n" +" cols = vec4(group1.ab, group2.ab) + vec4(group3.rg, group4.rg) +\n" +" mix(vec4(group1.rg, group2.rg), vec4(group3.ab, group4.ab), offset.y);\n" +" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n" +"# else\n" +"# ifdef GL_EXT_gpu_shader4\n" +" vec2 center = shadowmaptc.xy - 0.5*ShadowMap_TextureScale.xy, offset = fract(center*ShadowMap_TextureScale.zw);\n" +"# define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n" +"# else\n" +" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale.zw - 0.5, offset = fract(center);\n" +"# define texval(x, y) texture2D(Texture_ShadowMap2D, (center + vec2(x, y))*ShadowMap_TextureScale.xy).r \n" +"# endif\n" +" vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0))),\n" +" row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0))),\n" +" row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0))),\n" +" row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0))),\n" +" cols = row2 + row3 + mix(row1, row4, offset.y);\n" +" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n" +"# endif\n" +"# else\n" " f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy).r);\n" +"# endif\n" "# endif\n" " return f;\n" "}\n" diff --git a/r_shadow.c b/r_shadow.c index b6bfd221..2f17a212 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -1482,10 +1482,8 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size) nearclip = r_shadow_shadowmapping_nearclip.value / rsurface.rtlight->radius; farclip = 1.0f; bias = r_shadow_shadowmapping_bias.value * nearclip * (1024.0f / size);// * rsurface.rtlight->radius; - r_shadow_shadowmap_texturescale[2] = 0.5f + 0.5f * (farclip + nearclip) / (farclip - nearclip); - r_shadow_shadowmap_texturescale[3] = -nearclip * farclip / (farclip - nearclip) - 0.5f * bias; - r_shadow_shadowmap_parameters[2] = r_shadow_shadowmap_texturescale[2]; - r_shadow_shadowmap_parameters[3] = r_shadow_shadowmap_texturescale[3]; + r_shadow_shadowmap_parameters[2] = 0.5f + 0.5f * (farclip + nearclip) / (farclip - nearclip); + r_shadow_shadowmap_parameters[3] = -nearclip * farclip / (farclip - nearclip) - 0.5f * bias; if (r_shadow_shadowmode == 1) { // complex unrolled cube approach (more flexible) @@ -1609,10 +1607,12 @@ void R_Shadow_RenderMode_ShadowMap(int side, qboolean clear, int size) R_Viewport_InitCubeSideView(&viewport, &rsurface.rtlight->matrix_lighttoworld, side, size, nearclip, farclip, NULL); r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]); r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureWidth(r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]); - r_shadow_shadowmap_parameters[0] = r_shadow_shadowmap_texturescale[0]; - r_shadow_shadowmap_parameters[1] = r_shadow_shadowmap_texturescale[1]; + r_shadow_shadowmap_parameters[0] = 1.0f; + r_shadow_shadowmap_parameters[1] = 1.0f; r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAPCUBESIDE; } + r_shadow_shadowmap_texturescale[2] = 1.0f / r_shadow_shadowmap_texturescale[0]; + r_shadow_shadowmap_texturescale[3] = 1.0f / r_shadow_shadowmap_texturescale[1]; CHECKGLERROR R_SetViewport(&viewport); GL_PolygonOffset(0, 0); -- 2.39.2