From c1088c1abc1cf540eb7e1134b3bde9ae402b514b Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Mon, 2 Oct 2017 07:54:05 -0500 Subject: [PATCH] Distance field EffectMode (#1546) * Distance field EffectMode (supports MSDF and the regular sort) --- Data/Shaders/GLSL/Distance field.frag | 27 +++++++++++++++++++++++++++ Data/Shaders/GLSL/Distance field.vert | 10 ++++++++++ src/RageDisplay_OGL.cpp | 8 ++++++++ src/RageTypes.cpp | 4 +++- src/RageTypes.h | 1 + 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 Data/Shaders/GLSL/Distance field.frag create mode 100644 Data/Shaders/GLSL/Distance field.vert diff --git a/Data/Shaders/GLSL/Distance field.frag b/Data/Shaders/GLSL/Distance field.frag new file mode 100644 index 0000000000..5853eeeb2e --- /dev/null +++ b/Data/Shaders/GLSL/Distance field.frag @@ -0,0 +1,27 @@ +uniform sampler2D Texture1; + +varying vec2 texCoords; +varying vec4 vertexColor; + +float aastep(float threshold, float dist) { + float afwidth = 0.75 * length(vec2(dFdx(dist), dFdy(dist))); + return smoothstep(threshold - afwidth, threshold + afwidth, dist); +} + +float median(float r, float g, float b) { + return max(min(r, g), min(max(r, g), b)); +} + +const float distanceThreshold = 0.5; + +float sample(vec2 tc) { + vec3 texel = texture2D(Texture1, tc).rgb; + float dist = median(texel.r, texel.g, texel.b); + return aastep(distanceThreshold, dist); +} + +void main(void) +{ + float dfValue = sample(texCoords); + gl_FragColor = vec4(vertexColor.rgb, vertexColor.a * dfValue); +} diff --git a/Data/Shaders/GLSL/Distance field.vert b/Data/Shaders/GLSL/Distance field.vert new file mode 100644 index 0000000000..1d8a59cf10 --- /dev/null +++ b/Data/Shaders/GLSL/Distance field.vert @@ -0,0 +1,10 @@ +//We need this shader to pass the vertex color to the frag shader + +varying vec4 vertexColor; +varying vec2 texCoords; + +void main(void) { + vertexColor = gl_Color; + texCoords = gl_MultiTexCoord0.st; + gl_Position = gl_Vertex * gl_ModelViewProjectionMatrix; +} diff --git a/src/RageDisplay_OGL.cpp b/src/RageDisplay_OGL.cpp index cdfffd846d..e136fddc41 100644 --- a/src/RageDisplay_OGL.cpp +++ b/src/RageDisplay_OGL.cpp @@ -364,6 +364,8 @@ GLhandleARB LoadShader( GLenum ShaderType, RString sFile, vector asDefi secondaryShader = CompileShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Cel.frag", asDefines); else if (sFile == "Data/Shaders/GLSL/Shell.vert") secondaryShader = CompileShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Shell.frag", asDefines); + else if (sFile == "Data/Shaders/GLSL/Distance field.vert") + secondaryShader = CompileShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Distance field.frag", asDefines); GLhandleARB hShader = CompileShader( ShaderType, sFile, asDefines ); if (hShader == 0) @@ -405,6 +407,7 @@ static GLhandleARB g_hScreenShader = 0; static GLhandleARB g_hYUYV422Shader = 0; static GLhandleARB g_gShellShader = 0; static GLhandleARB g_gCelShader = 0; +static GLhandleARB g_gDistanceFieldShader = 0; void InitShaders() { @@ -419,6 +422,7 @@ void InitShaders() // these two are for dancing characters and are both actually shader pairs g_gShellShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Shell.vert", asDefines ); g_gCelShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Cel.vert", asDefines ); + g_gDistanceFieldShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Distance field.vert", asDefines ); // effects g_bUnpremultiplyShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Unpremultiply.frag", asDefines ); @@ -1798,6 +1802,8 @@ void RageDisplay_Legacy::SetEffectMode( EffectMode effect ) case EffectMode_YUYV422: hShader = g_hYUYV422Shader; break; + case EffectMode_DistanceField: + hShader = g_gDistanceFieldShader; default: break; } @@ -1844,6 +1850,8 @@ bool RageDisplay_Legacy::IsEffectModeSupported( EffectMode effect ) return g_hScreenShader != 0; case EffectMode_YUYV422: return g_hYUYV422Shader != 0; + case EffectMode_DistanceField: + return g_gDistanceFieldShader != 0; default: return false; } diff --git a/src/RageTypes.cpp b/src/RageTypes.cpp index b554a042e7..8f5477f02c 100644 --- a/src/RageTypes.cpp +++ b/src/RageTypes.cpp @@ -183,7 +183,9 @@ static const char *EffectModeNames[] = "Overlay", "Screen", - "YUYV422" + "YUYV422", + /* Draws a graphic from a signed distance field. */ + "DistanceField" }; XToString( EffectMode ); LuaXType( EffectMode ); diff --git a/src/RageTypes.h b/src/RageTypes.h index 40af928dc3..c66f635d86 100644 --- a/src/RageTypes.h +++ b/src/RageTypes.h @@ -51,6 +51,7 @@ enum EffectMode EffectMode_Overlay, EffectMode_Screen, EffectMode_YUYV422, + EffectMode_DistanceField, NUM_EffectMode, EffectMode_Invalid };