From 380603d7cee9532a309925305bea986c58e1ffaf Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 30 Nov 2013 02:49:09 +0000 Subject: [PATCH] Patch from graphitemaster adding r_fxaa cvar, this enables the popular pseudo-antialiasing method in postprocess. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12029 d7cf8633-e32d-0410-b094-e92efae38249 ::stable-branch::merge=bf5e31aa967e11a3ee0ab9f39d1d17519f720326 --- gl_rmain.c | 6 +++- model_brush.c | 2 ++ render.h | 1 + shader_glsl.h | 52 ++++++++++++++++++++++++++++++ shader_hlsl.h | 88 +++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 138 insertions(+), 11 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 81287ccb..338950aa 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -881,8 +881,9 @@ enum SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math) SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines) + SHADERSTATICPARM_FXAA = 13 ///< fast approximate anti aliasing }; -#define SHADERSTATICPARMS_COUNT 13 +#define SHADERSTATICPARMS_COUNT 14 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT]; static int shaderstaticparms_count = 0; @@ -916,6 +917,8 @@ qboolean R_CompileShader_CheckStaticParms(void) if (r_glsl_postprocess_uservec4_enable.integer) R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4); } + if (r_fxaa.integer) + R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_FXAA); if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0) R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD); @@ -956,6 +959,7 @@ static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permu R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER"); R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING"); R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES"); + R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_FXAA, "USEFXAA"); } /// information about each possible shader permutation diff --git a/model_brush.c b/model_brush.c index b8e64da4..eba42f52 100644 --- a/model_brush.c +++ b/model_brush.c @@ -39,6 +39,7 @@ cvar_t r_subdivisions_collision_mintess = {0, "r_subdivisions_collision_mintess" cvar_t r_subdivisions_collision_maxtess = {0, "r_subdivisions_collision_maxtess", "1024", "maximum number of subdivisions (prevents curves beyond a certain detail level, limits smoothing)"}; cvar_t r_subdivisions_collision_maxvertices = {0, "r_subdivisions_collision_maxvertices", "4225", "maximum vertices allowed per subdivided curve"}; cvar_t r_trippy = {0, "r_trippy", "0", "easter egg"}; +cvar_t r_fxaa = {CVAR_SAVE, "r_fxaa", "0", "fast approximate anti aliasing"}; cvar_t mod_noshader_default_offsetmapping = {CVAR_SAVE, "mod_noshader_default_offsetmapping", "1", "use offsetmapping by default on all surfaces that are not using q3 shader files"}; cvar_t mod_obj_orientation = {0, "mod_obj_orientation", "1", "fix orientation of OBJ models to the usual conventions (if zero, use coordinates as is)"}; cvar_t mod_q3bsp_curves_collisions = {0, "mod_q3bsp_curves_collisions", "1", "enables collisions with curves (SLOW)"}; @@ -83,6 +84,7 @@ void Mod_BrushInit(void) Cvar_RegisterVariable(&r_subdivisions_collision_maxtess); Cvar_RegisterVariable(&r_subdivisions_collision_maxvertices); Cvar_RegisterVariable(&r_trippy); + Cvar_RegisterVariable(&r_fxaa); Cvar_RegisterVariable(&mod_noshader_default_offsetmapping); Cvar_RegisterVariable(&mod_obj_orientation); Cvar_RegisterVariable(&mod_q3bsp_curves_collisions); diff --git a/render.h b/render.h index 090e92bc..b91bde74 100644 --- a/render.h +++ b/render.h @@ -55,6 +55,7 @@ extern cvar_t gl_flashblend; extern cvar_t r_novis; extern cvar_t r_trippy; +extern cvar_t r_fxaa; extern cvar_t r_lerpsprites; extern cvar_t r_lerpmodels; diff --git a/shader_glsl.h b/shader_glsl.h index b8a441b0..1c6cb906 100644 --- a/shader_glsl.h +++ b/shader_glsl.h @@ -245,10 +245,62 @@ "// uniform mediump vec4 UserVec4;\n", "// uniform highp float ClientTime;\n", "uniform mediump vec2 PixelSize;\n", +"\n", +"#ifdef USEFXAA\n", +"// graphitemaster: based off the white paper by Timothy Lottes\n", +"// http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf\n", +"vec4 fxaa(vec4 inColor, float maxspan)\n", +"{\n", +" vec4 ret = inColor; // preserve old\n", +" float mulreduct = 1.0/maxspan;\n", +" float minreduct = (1.0 / 128.0);\n", +"\n", +" // directions\n", +" vec3 NW = texture2D(Texture_First, TexCoord1 + (vec2(-1.0, -1.0) * PixelSize)).xyz;\n", +" vec3 NE = texture2D(Texture_First, TexCoord1 + (vec2(+1.0, -1.0) * PixelSize)).xyz;\n", +" vec3 SW = texture2D(Texture_First, TexCoord1 + (vec2(-1.0, +1.0) * PixelSize)).xyz;\n", +" vec3 SE = texture2D(Texture_First, TexCoord1 + (vec2(+1.0, +1.0) * PixelSize)).xyz;\n", +" vec3 M = texture2D(Texture_First, TexCoord1).xyz;\n", +"\n", +" // luminance directions\n", +" vec3 luma = vec3(0.299, 0.587, 0.114);\n", +" float lNW = dot(NW, luma);\n", +" float lNE = dot(NE, luma);\n", +" float lSW = dot(SW, luma);\n", +" float lSE = dot(SE, luma);\n", +" float lM = dot(M, luma);\n", +" float lMin = min(lM, min(min(lNW, lNE), min(lSW, lSE)));\n", +" float lMax = max(lM, max(max(lNW, lNE), max(lSW, lSE)));\n", +"\n", +" // direction and reciprocal\n", +" vec2 dir = vec2(-((lNW + lNE) - (lSW + lSE)), ((lNW + lSW) - (lNE + lSE)));\n", +" float rcp = 1.0/(min(abs(dir.x), abs(dir.y)) + max((lNW + lNE + lSW + lSE) * (0.25 * mulreduct), minreduct));\n", +"\n", +" // span\n", +" dir = min(vec2(maxspan, maxspan), max(vec2(-maxspan, -maxspan), dir * rcp)) * PixelSize;\n", +"\n", +" vec3 rA = (1.0/2.0) * (\n", +" texture2D(Texture_First, TexCoord1 + dir * (1.0/3.0 - 0.5)).xyz +\n", +" texture2D(Texture_First, TexCoord1 + dir * (2.0/3.0 - 0.5)).xyz);\n", +" vec3 rB = rA * (1.0/2.0) + (1.0/4.0) * (\n", +" texture2D(Texture_First, TexCoord1 + dir * (0.0/3.0 - 0.5)).xyz +\n", +" texture2D(Texture_First, TexCoord1 + dir * (3.0/3.0 - 0.5)).xyz);\n", +" float lB = dot(rB, luma);\n", +"\n", +" ret.xyz = ((lB < lMin) || (lB > lMax)) ? rA : rB;\n", +" ret.a = 1.0;\n", +" return ret;\n", +"}\n", +"#endif\n", +"\n", "void main(void)\n", "{\n", " dp_FragColor = dp_texture2D(Texture_First, TexCoord1);\n", "\n", +"#ifdef USEFXAA\n", +" dp_FragColor = fxaa(dp_FragColor, 8.0); // 8.0 can be changed for larger span\n", +"#endif\n", +"\n", "#ifdef USEPOSTPROCESSING\n", "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n", "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n", diff --git a/shader_hlsl.h b/shader_hlsl.h index 7881aa6a..e81e6039 100644 --- a/shader_hlsl.h +++ b/shader_hlsl.h @@ -31,9 +31,10 @@ "#ifdef USETRIPPY\n", "// LordHavoc: based on shader code linked at: http://www.youtube.com/watch?v=JpksyojwqzE\n", "// tweaked scale\n", -"float4 TrippyVertex(float4 position)\n", +"float4 TrippyVertex\n", "(\n", -"uniform float ClientTime : register(c2)\n", +"float4 position,\n", +"float ClientTime\n", ")\n", "{\n", " float worldTime = ClientTime;\n", @@ -59,13 +60,14 @@ "(\n", "float4 gl_Vertex : POSITION,\n", "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n", +"uniform float ClientTime : register(c2),\n", "out float4 gl_Position : POSITION,\n", "out float Depth : TEXCOORD0\n", ")\n", "{\n", " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n", "#ifdef USETRIPPY\n", -" gl_Position = TrippyVertex(gl_Position);\n", +" gl_Position = TrippyVertex(gl_Position, ClientTime);\n", "#endif\n", " Depth = gl_Position.z;\n", "}\n", @@ -100,8 +102,10 @@ "float4 gl_MultiTexCoord0 : TEXCOORD0,\n", "float4 gl_MultiTexCoord4 : TEXCOORD4,\n", "out float4 gl_Position : POSITION,\n", -"out float2 TexCoord1 : TEXCOORD0,\n", -"out float2 TexCoord2 : TEXCOORD1\n", +"out float2 TexCoord1 : TEXCOORD0\n", +"#ifdef USEBLOOM\n", +", out float2 TexCoord2 : TEXCOORD1\n", +"#endif\n", ")\n", "{\n", " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n", @@ -113,10 +117,65 @@ "#endif\n", "\n", "#ifdef FRAGMENT_SHADER\n", +"#ifdef USEFXAA\n", +"// graphitemaster: based off the white paper by Timothy Lottes\n", +"// http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf\n", +"float4 fxaa\n", +"(\n", +" float4 inColor,\n", +" float maxspan,\n", +" float2 TexCoord1,\n", +" uniform sampler Texture_First,\n", +" uniform float2 PixelSize\n", +")\n", +"{\n", +" float4 ret = inColor; // preserve old\n", +" float mulreduct = 1.0/maxspan;\n", +" float minreduct = (1.0 / 128.0);\n", +"\n", +" float3 NW = tex2D(Texture_First, TexCoord1 + (float2(-1.0, -1.0) * PixelSize)).xyz;\n", +" float3 NE = tex2D(Texture_First, TexCoord1 + (float2(+1.0, -1.0) * PixelSize)).xyz;\n", +" float3 SW = tex2D(Texture_First, TexCoord1 + (float2(-1.0, +1.0) * PixelSize)).xyz;\n", +" float3 SE = tex2D(Texture_First, TexCoord1 + (float2(+1.0, +1.0) * PixelSize)).xyz;\n", +" float3 M = tex2D(Texture_First, TexCoord1).xyz;\n", +"\n", +" // luminance directions\n", +" float3 luma = float3(0.299, 0.587, 0.114);\n", +" float lNW = dot(NW, luma);\n", +" float lNE = dot(NE, luma);\n", +" float lSW = dot(SW, luma);\n", +" float lSE = dot(SE, luma);\n", +" float lM = dot(M, luma);\n", +" float lMin = min(lM, min(min(lNW, lNE), min(lSW, lSE)));\n", +" float lMax = max(lM, max(max(lNW, lNE), max(lSW, lSE)));\n", +"\n", +" // direction and reciprocal\n", +" float2 dir = float2(-((lNW + lNE) - (lSW + lSE)), ((lNW + lSW) - (lNE + lSE)));\n", +" float rcp = 1.0/(min(abs(dir.x), abs(dir.y)) + max((lNW + lNE + lSW + lSE) * (0.25 * mulreduct), minreduct));\n", +"\n", +" // span\n", +" dir = min(float2(maxspan, maxspan), max(float2(-maxspan, -maxspan), dir * rcp)) * PixelSize;\n", +"\n", +" float3 rA = (1.0/2.0) * (\n", +" tex2D(Texture_First, TexCoord1 + dir * (1.0/3.0 - 0.5)).xyz +\n", +" tex2D(Texture_First, TexCoord1 + dir * (2.0/3.0 - 0.5)).xyz);\n", +" float3 rB = rA * (1.0/2.0) + (1.0/4.0) * (\n", +" tex2D(Texture_First, TexCoord1 + dir * (0.0/3.0 - 0.5)).xyz +\n", +" tex2D(Texture_First, TexCoord1 + dir * (3.0/3.0 - 0.5)).xyz);\n", +" float lB = dot(rB, luma);\n", +"\n", +" ret.xyz = ((lB < lMin) || (lB > lMax)) ? rA : rB;\n", +" ret.a = 1.0;\n", +" return ret;\n", +"}\n", +"#endif\n", +"\n", "void main\n", "(\n", "float2 TexCoord1 : TEXCOORD0,\n", +"#ifdef USEBLOOM\n", "float2 TexCoord2 : TEXCOORD1,\n", +"#endif\n", "uniform sampler Texture_First : register(s0),\n", "#ifdef USEBLOOM\n", "uniform sampler Texture_Second : register(s1),\n", @@ -142,6 +201,10 @@ "{\n", " dp_FragColor = tex2D(Texture_First, TexCoord1);\n", "\n", +"#ifdef USEFXAA\n", +" dp_FragColor = fxaa(dp_FragColor, 8.0, TexCoord1, Texture_First, PixelSize); // 8.0 can be changed for larger span\n", +"#endif\n", +"\n", "#ifdef USEPOSTPROCESSING\n", "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n", "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n", @@ -227,6 +290,7 @@ "float4 gl_Color : COLOR0,\n", "float4 gl_MultiTexCoord0 : TEXCOORD0,\n", "float4 gl_MultiTexCoord1 : TEXCOORD1,\n", +"uniform float ClientTime : register(c2),\n", "out float4 gl_Position : POSITION,\n", "#ifdef USEDIFFUSE\n", "out float2 TexCoord1 : TEXCOORD0,\n", @@ -246,7 +310,7 @@ "#endif\n", " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n", "#ifdef USETRIPPY\n", -" gl_Position = TrippyVertex(gl_Position);\n", +" gl_Position = TrippyVertex(gl_Position, ClientTime);\n", "#endif\n", "}\n", "#endif\n", @@ -363,6 +427,7 @@ "float4 gl_MultiTexCoord0 : TEXCOORD0,\n", "uniform float4x4 TexMatrix : register(c0),\n", "uniform float3 EyePosition : register(c24),\n", +"uniform float ClientTime : register(c2),\n", "#ifdef USEALPHAGENVERTEX\n", "out float4 gl_FrontColor : COLOR,\n", "#endif\n", @@ -379,7 +444,7 @@ " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n", " ModelViewProjectionPosition = gl_Position;\n", "#ifdef USETRIPPY\n", -" gl_Position = TrippyVertex(gl_Position);\n", +" gl_Position = TrippyVertex(gl_Position, ClientTime);\n", "#endif\n", "}\n", "#endif\n", @@ -448,6 +513,7 @@ "float4 gl_MultiTexCoord3 : TEXCOORD3,\n", "uniform float4x4 TexMatrix : register(c0),\n", "uniform float3 EyePosition : register(c24),\n", +"uniform float ClientTime : register(c2),\n", "#ifdef USEALPHAGENVERTEX\n", "out float4 gl_FrontColor : COLOR,\n", "#endif\n", @@ -466,7 +532,7 @@ " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n", " ModelViewProjectionPosition = gl_Position;\n", "#ifdef USETRIPPY\n", -" gl_Position = TrippyVertex(gl_Position);\n", +" gl_Position = TrippyVertex(gl_Position, ClientTime);\n", "#endif\n", "}\n", "#endif\n", @@ -762,6 +828,7 @@ "#ifdef USEOFFSETMAPPING\n", "uniform float3 EyePosition : register(c24),\n", "#endif\n", +"uniform float ClientTime : register(c2),\n", "out float4 gl_Position : POSITION,\n", "#ifdef USEVERTEXTEXTUREBLEND\n", "out float4 gl_FrontColor : COLOR,\n", @@ -792,7 +859,7 @@ " VectorR.xyz = mul(ModelViewMatrix, float4(gl_MultiTexCoord3.xyz, 0)).xyz;\n", " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n", "#ifdef USETRIPPY\n", -" gl_Position = TrippyVertex(gl_Position);\n", +" gl_Position = TrippyVertex(gl_Position, ClientTime);\n", "#endif\n", " VectorR.w = mul(ModelViewMatrix, gl_Vertex).z;\n", "}\n", @@ -1031,6 +1098,7 @@ "#ifdef USESHADOWMAPORTHO\n", "uniform float4x4 ShadowMapMatrix : register(c16),\n", "#endif\n", +"uniform float ClientTime : register(c2),\n", "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND) || defined(MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR) || defined(USEALPHAGENVERTEX)\n", "out float4 gl_FrontColor : COLOR,\n", "#endif\n", @@ -1122,7 +1190,7 @@ " ModelViewProjectionPosition = gl_Position;\n", "#endif\n", "#ifdef USETRIPPY\n", -" gl_Position = TrippyVertex(gl_Position);\n", +" gl_Position = TrippyVertex(gl_Position, ClientTime);\n", "#endif\n", "}\n", "#endif // VERTEX_SHADER\n", -- 2.39.2