From d9ae9a6ab5eee7526f1972209c42cd7c331aadfd Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 15 Feb 2012 23:34:35 +0000 Subject: [PATCH] added r_celshading cvar and GLSL shader code added r_celoutlines cvar and GLSL shader code git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11690 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 14 +++++++++- r_shadow.c | 2 +- shader_glsl.h | 72 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 868fb5cc..34933296 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -132,6 +132,8 @@ cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"}; cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"}; cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"}; +cvar_t r_celshading = {CVAR_SAVE, "r_celshading", "0", "cartoon-style light shading"}; +cvar_t r_celoutlines = {CVAR_SAVE, "r_celoutlines", "0", "cartoon-style outlines (requires r_shadow_deferred)"}; cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"}; cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"}; @@ -853,8 +855,10 @@ enum SHADERSTATICPARM_SHADOWMAPPCF_1 = 8, ///< PCF 1 SHADERSTATICPARM_SHADOWMAPPCF_2 = 9, ///< PCF 2 SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler + SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math) + SHADERSTATICPARM_CELOUTLINE = 12, ///< celoutline (depth buffer analysis to produce outlines) }; -#define SHADERSTATICPARMS_COUNT 11 +#define SHADERSTATICPARMS_COUNT 13 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT]; static int shaderstaticparms_count = 0; @@ -897,6 +901,10 @@ qboolean R_CompileShader_CheckStaticParms(void) R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_2); else if (r_shadow_shadowmappcf) R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_1); + else if (r_celshading.integer) + R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELSHADING); + else if (r_celoutlines.integer) + R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELOUTLINE); return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0; } @@ -922,6 +930,8 @@ static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permu R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_1, "USESHADOWMAPPCF 1"); R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_2, "USESHADOWMAPPCF 2"); R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER"); + R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING"); + R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES"); } /// information about each possible shader permutation @@ -4263,6 +4273,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_glsl_postprocess_uservec2_enable); Cvar_RegisterVariable(&r_glsl_postprocess_uservec3_enable); Cvar_RegisterVariable(&r_glsl_postprocess_uservec4_enable); + Cvar_RegisterVariable(&r_celshading); + Cvar_RegisterVariable(&r_celoutlines); Cvar_RegisterVariable(&r_water); Cvar_RegisterVariable(&r_water_resolutionmultiplier); diff --git a/r_shadow.c b/r_shadow.c index bdf4f2c5..40a35c78 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -4550,7 +4550,7 @@ void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *color r_shadow_prepass_width = vid.width; r_shadow_prepass_height = vid.height; r_shadow_prepassgeometrydepthbuffer = R_LoadTextureRenderBuffer(r_shadow_texturepool, "prepassgeometrydepthbuffer", vid.width, vid.height, TEXTYPE_DEPTHBUFFER24); - r_shadow_prepassgeometrynormalmaptexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrynormalmap", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER16F, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); + r_shadow_prepassgeometrynormalmaptexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrynormalmap", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER32F, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); r_shadow_prepasslightingdiffusetexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingdiffuse", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER16F, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); r_shadow_prepasslightingspeculartexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingspecular", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER16F, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); diff --git a/shader_glsl.h b/shader_glsl.h index c7b5ebff..722fc3d6 100644 --- a/shader_glsl.h +++ b/shader_glsl.h @@ -2,6 +2,22 @@ "// written by Forest 'LordHavoc' Hale\n" "// shadowmapping enhancements by Lee 'eihrul' Salzman\n" "\n" +"#ifdef USECELSHADING\n" +"# define SHADEDIFFUSE myhalf diffuse = cast_myhalf(min(max(float(dot(surfacenormal, lightnormal)) * 2.0, 0.0), 1.0));\n" +"# ifdef USEEXACTSPECULARMATH\n" +"# define SHADESPECULAR(specpow) myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), eyenormal))*-1.0, 0.0)), 1.0 + specpow);specular = max(0.0, specular * 10.0 - 9.0);\n" +"# else\n" +"# define SHADESPECULAR(specpow) myhalf3 specularnormal = normalize(lightnormal + eyenormal);myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + specpow);specular = max(0.0, specular * 10.0 - 9.0);\n" +"# endif\n" +"#else\n" +"# define SHADEDIFFUSE myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n" +"# ifdef USEEXACTSPECULARMATH\n" +"# define SHADESPECULAR(specpow) myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), eyenormal))*-1.0, 0.0)), 1.0 + specpow);\n" +"# else\n" +"# define SHADESPECULAR(specpow) myhalf3 specularnormal = normalize(lightnormal + eyenormal);myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + specpow);\n" +"# endif\n" +"#endif\n" +"\n" "#ifdef GLSL130\n" "precision highp float;\n" "# ifdef VERTEX_SHADER\n" @@ -677,6 +693,9 @@ "uniform sampler2D Texture_ScreenNormalMap;\n" "#endif\n" "#ifdef USEDEFERREDLIGHTMAP\n" +"#ifdef USECELOUTLINES\n" +"uniform sampler2D Texture_ScreenNormalMap;\n" +"#endif\n" "uniform sampler2D Texture_ScreenDiffuse;\n" "uniform sampler2D Texture_ScreenSpecular;\n" "#endif\n" @@ -1064,23 +1083,18 @@ " // surfacenormal = pixel normal in viewspace\n" " // LightVector = pixel to light in viewspace\n" " // CubeVector = pixel in lightspace\n" -" // eyevector = pixel to view in viewspace\n" +" // eyenormal = pixel to view direction in viewspace\n" " vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n" " myhalf fade = cast_myhalf(dp_texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n" "#ifdef USEDIFFUSE\n" " // calculate diffuse shading\n" " myhalf3 lightnormal = cast_myhalf3(normalize(LightPosition - position));\n" -" myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n" +"SHADEDIFFUSE\n" "#endif\n" "#ifdef USESPECULAR\n" " // calculate directional shading\n" -" vec3 eyevector = position * -1.0;\n" -"# ifdef USEEXACTSPECULARMATH\n" -" myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), 1.0 + SpecularPower * normalmap.a);\n" -"# else\n" -" myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(eyevector)));\n" -" myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * normalmap.a);\n" -"# endif\n" +" myhalf3 eyenormal = -normalize(cast_myhalf3(position));\n" +"SHADESPECULAR(SpecularPower * normalmap.a)\n" "#endif\n" "\n" "#if defined(USESHADOWMAP2D)\n" @@ -1326,6 +1340,10 @@ " diffusetex += cast_myhalf3(offsetMappedTexture2D(Texture_ReflectMask)) * cast_myhalf3(dp_textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n" "#endif\n" "\n" +"#ifdef USESPECULAR\n" +" myhalf3 eyenormal = normalize(cast_myhalf3(EyeVectorFogDepth.xyz));\n" +"#endif\n" +"\n" "\n" "\n" "\n" @@ -1333,15 +1351,10 @@ " // light source\n" "#ifdef USEDIFFUSE\n" " myhalf3 lightnormal = cast_myhalf3(normalize(LightVector));\n" -" myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n" +"SHADEDIFFUSE\n" " color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n" "#ifdef USESPECULAR\n" -"#ifdef USEEXACTSPECULARMATH\n" -" myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, 0.0)), 1.0 + SpecularPower * glosstex.a);\n" -"#else\n" -" myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(EyeVectorFogDepth.xyz)));\n" -" myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a);\n" -"#endif\n" +"SHADESPECULAR(SpecularPower * glosstex.a)\n" " color.rgb += glosstex.rgb * (specular * Color_Specular);\n" "#endif\n" "#else\n" @@ -1429,14 +1442,9 @@ "\n" "#ifdef SHADING\n" "# ifdef USEDIFFUSE\n" -" myhalf diffuse = cast_myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n" +"SHADEDIFFUSE\n" "# ifdef USESPECULAR\n" -"# ifdef USEEXACTSPECULARMATH\n" -" myhalf specular = pow(cast_myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVectorFogDepth.xyz)))*-1.0, 0.0)), 1.0 + SpecularPower * glosstex.a);\n" -"# else\n" -" myhalf3 specularnormal = normalize(lightnormal + cast_myhalf3(normalize(EyeVectorFogDepth.xyz)));\n" -" myhalf specular = pow(cast_myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), 1.0 + SpecularPower * glosstex.a);\n" -"# endif\n" +"SHADESPECULAR(SpecularPower * glosstex.a)\n" " color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n" "# else\n" " color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n" @@ -1490,6 +1498,24 @@ "#endif\n" "#endif\n" "\n" +"#ifdef USECELOUTLINES\n" +"# ifdef USEDEFERREDLIGHTMAP\n" +"// vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n" +" vec4 ScreenTexCoordStep = vec4(PixelToScreenTexCoord.x, 0.0, 0.0, PixelToScreenTexCoord.y);\n" +" vec4 DepthNeighbors;\n" +" float DepthCenter = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord).b;\n" +" DepthNeighbors.x = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord - ScreenTexCoordStep.xy).b;\n" +" DepthNeighbors.y = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord + ScreenTexCoordStep.xy).b;\n" +" DepthNeighbors.z = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord + ScreenTexCoordStep.zw).b;\n" +" DepthNeighbors.w = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord - ScreenTexCoordStep.zw).b;\n" +" float DepthAverage = dot(DepthNeighbors, vec4(0.25, 0.25, 0.25, 0.25));\n" +" float DepthDelta = abs(dot(DepthNeighbors.xy, vec2(-1.0, 1.0))) + abs(dot(DepthNeighbors.zw, vec2(-1.0, 1.0)));\n" +"// color.rgb = vec3(1.0, 1.0, 1.0);\n" +" color.rgb *= max(0.25, 1.0 - max(0.0, abs(DepthCenter - DepthAverage) - 0.07 * DepthDelta) / (0.03 + 0.03 * DepthDelta));\n" +"// color.rgb *= step(abs(DepthCenter - DepthAverage), 0.2 * DepthDelta);\n" +"# endif\n" +"#endif\n" +"\n" "#ifdef USEFOG\n" " color.rgb = FogVertex(color);\n" "#endif\n" -- 2.39.2