New update:

- Added Paint filter.
 - Tweaked order of shaders.
 - Allow more grain parameters to be configured.
This commit is contained in:
Marisa the Magician 2021-11-06 17:25:07 +01:00
commit 595159703c
11 changed files with 259 additions and 67 deletions

View file

@ -44,12 +44,14 @@ Blurring followed by sharpening, followed by chromatic aberration. This is a mem
Darkens the edges of the screen. Comes with "border blur", which also blurs said edges.
### Paint
Makes the game look like an oil painting, if you somehow are interested in that.
### RetroFX
A combo of downscaling and palette reduction (with optional dither), which has been a staple of MariENB for years. There's a multitude of palettes available to choose from. Most IWADs are covered, along with some notable megawads, various DOS games, and a couple "standard" palettes.
Not available yet are the features for aspect ratio correction, overscan/underscan or the old CRT filter (which wasn't exactly all that good, really).
## Missing Shaders
### Bloom
@ -68,10 +70,10 @@ Not needed, GZDoom implements its own.
These aren't "general purpose" enough to be included.
### Paint Filter
### CRT Filter
Might add it, maybe???
Screen curvature + aperture grille overlay. I'm not going to add this back because honestly, it's dumb and ugly.
### SMAA
This needs to be part of GZDoom, honestly.
Can't be done due to the limited features of user shaders. It should be part of GZDoom itself, honestly.

View file

@ -8,6 +8,14 @@ nosave float mfx_lsharpblend = 6.;
nosave bool mfx_ne = false;
nosave float mfx_ni = .05;
nosave float mfx_ns = 0.;
nosave float mfx_nf = .05;
nosave float mfx_nm1_r = 2.05;
nosave float mfx_nm1_g = 3.11;
nosave float mfx_nm1_b = 2.22;
nosave float mfx_nk = .04;
nosave float mfx_nm2_r = 4.25;
nosave float mfx_nm2_g = 9.42;
nosave float mfx_nm2_b = 6.29;
nosave float mfx_np = 4.;
nosave float mfx_bnp = 1.5;
nosave int mfx_nb = 2;
@ -98,6 +106,8 @@ nosave float mfx_vigbump = 0.;
nosave int mfx_vigshape = 1;
nosave int mfx_vigmode = 0;
nosave bool mfx_paintenable = false;
nosave bool mfx_retroenable = false;
nosave int mfx_retroscalemode = 0;
nosave int mfx_bres_x = 640;

View file

@ -7,6 +7,32 @@ HardwareShader postprocess scene
Uniform float sharpblend
}
HardwareShader postprocess scene
{
Name "mfx_grain"
Shader "shaders/glsl/mfx_grain.fp" 330
Uniform float Timer
Uniform float nf
Uniform float ni
Uniform float ns
Uniform vec3 nm1
Uniform float nk
Uniform vec3 nm2
Uniform float np
Uniform float bnp
Uniform int nb
Texture NoiseTexture "textures/mfxnoise.png"
}
HardwareShader postprocess scene
{
Name "mfx_dirt"
Shader "shaders/glsl/mfx_dirt.fp" 330
Uniform float dirtcfactor
Uniform float dirtmc
Texture NoiseTexture "textures/mfxdirt.png"
}
HardwareShader postprocess scene
{
Name "mfx_grading"
@ -74,6 +100,37 @@ HardwareShader postprocess scene
Uniform float hsval_m
}
HardwareShader postprocess scene
{
Name "mfx_borderblur"
Shader "shaders/glsl/mfx_borderblur.fp" 330
Uniform float vigpow
Uniform float vigmul
Uniform float vigbump
Uniform int vigshape
Uniform float bblurpow
Uniform float bblurmul
Uniform float bblurbump
Uniform float bblurradius
Texture VignetteTexture "textures/mfxvig.png"
}
HardwareShader postprocess scene
{
Name "mfx_paint_pass1"
Shader "shaders/glsl/mfx_paint_pass1.fp" 330
}
HardwareShader postprocess scene
{
Name "mfx_paint_pass2"
Shader "shaders/glsl/mfx_paint_pass2.fp" 330
}
HardwareShader postprocess scene
{
Name "mfx_paint_pass3"
Shader "shaders/glsl/mfx_paint_pass3.fp" 330
}
HardwareShader postprocess scene
{
Name "mfx_bss_blur"
@ -93,44 +150,6 @@ HardwareShader postprocess scene
Shader "shaders/glsl/mfx_bss_shift.fp" 330
Uniform float bssshiftradius
}
HardwareShader postprocess scene
{
Name "mfx_borderblur"
Shader "shaders/glsl/mfx_borderblur.fp" 330
Uniform float vigpow
Uniform float vigmul
Uniform float vigbump
Uniform int vigshape
Uniform float bblurpow
Uniform float bblurmul
Uniform float bblurbump
Uniform float bblurradius
Texture VignetteTexture "textures/mfxvig.png"
}
HardwareShader postprocess scene
{
Name "mfx_grain"
Shader "shaders/glsl/mfx_grain.fp" 330
Uniform float Timer
Uniform float ni
Uniform float ns
Uniform float np
Uniform float bnp
Uniform int nb
Texture NoiseTexture "textures/mfxnoise.png"
}
HardwareShader postprocess scene
{
Name "mfx_dirt"
Shader "shaders/glsl/mfx_dirt.fp" 330
Uniform float dirtcfactor
Uniform float dirtmc
Texture NoiseTexture "textures/mfxdirt.png"
}
HardwareShader postprocess scene
{
Name "mfx_vignette"

View file

@ -1,8 +1,9 @@
[enu default]
MFX_TITLE="MariFX Options";
MFX_BLENDMODE1="Add";
MFX_BLENDMODE2="Overlay";
MFX_BLENDMODE3="Dark Mask";
MFX_BLENDMODE1="Mix";
MFX_BLENDMODE2="Add";
MFX_BLENDMODE3="Overlay";
MFX_BLENDMODE4="Dark Mask";
MFX_VIGSHAPE1="Circle";
MFX_VIGSHAPE2="Box";
MFX_VIGSHAPE3="Texture";
@ -100,8 +101,16 @@ MFX_LSHARPRADIUS="Sharpen Radius";
MFX_LSHARPTRESHOLD="Sharpen Threshold";
MFX_LSHARPSTRENGTH="Sharpen Strength";
MFX_GRAIN="Film Grain";
MFX_NF="Grain Speed";
MFX_NI="Grain Intensity";
MFX_NS="Grain Saturation";
MFX_NM1_R="Grain Pass 1 Magnification 1";
MFX_NM1_G="Grain Pass 1 Magnification 2";
MFX_NM1_B="Grain Pass 1 Magnification 3";
MFX_NK="Grain Two-Pass Factor";
MFX_NM2_R="Grain Pass 2 Magnification 1";
MFX_NM2_G="Grain Pass 2 Magnification 2";
MFX_NM2_B="Grain Pass 2 Magnification 3";
MFX_NP="Grain Contrast";
MFX_NB="Grain Blend Mode";
MFX_BNP="Grain Dark Mask Contrast";
@ -186,6 +195,7 @@ MFX_BBLURPOW="Blur Gamma";
MFX_BBLURMUL="Blur Intensity";
MFX_BBLURBUMP="Blur Offset";
MFX_BBLURRADIUS="Blur Radius";
MFX_PAINT="Painting Filter";
MFX_RETROFX="Retro FX";
MFX_RETROENABLE="Enable Downscale";
MFX_RETROSCALEMODE="Scaling Mode";

View file

@ -12,6 +12,7 @@ OptionValue "MFXGrainBlend"
0, "$MFX_BLENDMODE1"
1, "$MFX_BLENDMODE2"
2, "$MFX_BLENDMODE3"
3, "$MFX_BLENDMODE4"
}
OptionValue "MFXVigShape"
@ -145,10 +146,18 @@ OptionMenu "MFXOptionsMenu"
StaticText " "
Option "$MFX_ENABLE", "mfx_ne", "YesNo"
MFXSlider "$MFX_NI", "mfx_ni", 0, 1, 0.01, 2
MFXSlider "$MFX_NF", "mfx_nf", -10, 10, 0.01, 2
MFXSlider "$MFX_NS", "mfx_ns", -1, 1, 0.01, 2
MFXSlider "$MFX_NP", "mfx_np", 0.5, 8, 0.01, 2
MFXSlider "$MFX_NP", "mfx_np", 0, 8, 0.01, 2
MFXSlider "$MFX_NM1_R", "mfx_nm1_r", 0, 10, 0.01, 2
MFXSlider "$MFX_NM1_G", "mfx_nm1_g", 0, 10, 0.01, 2
MFXSlider "$MFX_NM1_B", "mfx_nm1_b", 0, 10, 0.01, 2
MFXSlider "$MFX_NK", "mfx_nk", 0, 1, 0.01, 2
MFXSlider "$MFX_NM2_R", "mfx_nm2_r", 0, 10, 0.01, 2
MFXSlider "$MFX_NM2_G", "mfx_nm2_g", 0, 10, 0.01, 2
MFXSlider "$MFX_NM2_B", "mfx_nm2_b", 0, 10, 0.01, 2
Option "$MFX_NB", "mfx_nb", "MFXGrainBlend"
MFXSlider "$MFX_BNP", "mfx_bnp", 0.5, 10, 0.01, 2
MFXSlider "$MFX_BNP", "mfx_bnp", 0, 10, 0.01, 2
SafeCommand "$MFX_RESET", "event resetmfxvars 0"
StaticText " "
StaticText "$MFX_DIRT", "Gold"
@ -263,6 +272,11 @@ OptionMenu "MFXOptionsMenu"
MFXSlider "$MFX_BBLURRADIUS", "mfx_bblurradius", 0, 4, 0.01, 2
SafeCommand "$MFX_RESET", "event resetmfxvars 6"
StaticText " "
StaticText "$MFX_PAINT", "Gold"
StaticText " "
Option "$MFX_ENABLE", "mfx_paintenable", "YesNo"
SafeCommand "$MFX_RESET", "event resetmfxvars 11"
StaticText " "
StaticText "$MFX_RETROFX", "Gold"
StaticText " "
Option "$MFX_RETROENABLE", "mfx_retroenable", "YesNo"

View file

@ -24,12 +24,12 @@ void main()
{
vec4 res = texture(InputTexture,TexCoord);
res.rgb = pow(max(res.rgb,0.0),gradepow)*grademul;
float tonev = luminance(res.rgb);
vec3 tonecolor = gradecol*tonev;
res.rgb = res.rgb*(1.0-gradecolfact)+tonecolor*gradecolfact;
vec3 hsv = rgb2hsv(res.rgb);
hsv.y = clamp(pow(max(hsv.y,0.0),gradesatpow)*gradesatmul,0.0,1.0);
hsv.z = pow(max(hsv.z,0.0),gradevalpow)*gradevalmul;
res.rgb = hsv2rgb(hsv);
float tonev = luminance(res.rgb);
vec3 tonecolor = gradecol*tonev;
res.rgb = res.rgb*(1.0-gradecolfact)+tonecolor*gradecolfact;
FragColor = res;
}

View file

@ -2,24 +2,18 @@
Complex grain shader ported over from MariENB
(C)2012-2021 Marisa Kirisame
*/
const float nf = 0.0005;
const vec3 nm1 = vec3(2.05,3.11,2.22);
const float nk = 0.04;
const vec3 nm2 = vec3(4.25,9.42,6.29);
#define overlay(a,b) (a<0.5)?(2.0*a*b):(1.0-(2.0*(1.0-a)*(1.0-b)))
#define darkmask(a,b) (a>0.5)?(2.0*a*(0.5+b)):(1.0-2.0*(1.0-a)*(1.0-((0.5+b))))
vec3 grain( in vec3 res, in vec2 coord )
{
float ts = Timer*nf;
vec2 s1 = coord+vec2(0.0,ts);
vec2 s2 = coord+vec2(ts,0.0);
vec2 s1 = coord+vec2(0.,ts);
vec2 s2 = coord+vec2(ts,0.);
vec2 s3 = coord+vec2(ts,ts);
float n1, n2, n3;
vec2 bresl = textureSize(InputTexture,0);
vec2 nr = vec2(7.5);
nr.y *= bresl.y/bresl.x;
vec2 nr = bresl/256.;
n1 = texture(NoiseTexture,s1*nm1.x*nr).r;
n2 = texture(NoiseTexture,s2*nm1.y*nr).g;
n3 = texture(NoiseTexture,s3*nm1.z*nr).b;
@ -29,26 +23,27 @@ vec3 grain( in vec3 res, in vec2 coord )
n1 = texture(NoiseTexture,s1*nm2.x*nr).r;
n2 = texture(NoiseTexture,s2*nm2.y*nr).g;
n3 = texture(NoiseTexture,s3*nm2.z*nr).b;
float n4 = (n1+n2+n3)/3.0;
float n4 = (n1+n2+n3)/3.;
vec3 ng = vec3(n4);
vec3 nc = vec3(n1,n2,n3);
vec3 nt = pow(clamp(mix(ng,nc,ns),0.0,1.0),vec3(np));
if ( nb == 0 ) res.rgb += nt*ni;
else if ( nb == 1 )
vec3 nt = pow(clamp(mix(ng,nc,ns),.0,1.),vec3(np));
if ( nb == 1 ) res.rgb += nt*ni;
else if ( nb == 2 )
{
res.r = overlay(res.r,(nt.r*ni+0.5));
res.g = overlay(res.g,(nt.g*ni+0.5));
res.b = overlay(res.b,(nt.b*ni+0.5));
res.r = overlay(res.r,(nt.r*ni));
res.g = overlay(res.g,(nt.g*ni));
res.b = overlay(res.b,(nt.b*ni));
}
else
else if ( nb == 3 )
{
float bn = 1.0-clamp((res.r+res.g+res.b)/3.0,0.0,1.0);
float bn = 1.-clamp((res.r+res.g+res.b)/3.,0.,1.);
bn = pow(bn,bnp);
vec3 nn = clamp(nt*bn,vec3(0.0),vec3(1.0));
vec3 nn = clamp(nt*bn,vec3(0.),vec3(1.));
res.r = darkmask(res.r,(nn.r*ni));
res.g = darkmask(res.g,(nn.g*ni));
res.b = darkmask(res.b,(nn.b*ni));
}
else res.rgb = mix(res.rgb,nt,ni);
return res;
}

View file

@ -0,0 +1,52 @@
/*
Paint filter from MariENB (first pass Kuwahara filter)
(C)2012-2021 Marisa Kirisame
*/
void main()
{
vec2 coord = TexCoord;
vec4 res = texture(InputTexture,coord);
vec2 bresl = textureSize(InputTexture,0);
vec2 bof = 1./bresl;
float n = 16.;
vec3 m[4] = vec3[](vec3(0.),vec3(0.),vec3(0.),vec3(0.)),
s[4] = vec3[](vec3(0.),vec3(0.),vec3(0.),vec3(0.)),
c;
int i, j;
for ( i=-3; i<=0; i++ ) for ( j=-3; j<=0; j++ )
{
c = texture(InputTexture,coord+vec2(i,j)*bof).rgb;
m[0] += c;
s[0] += c*c;
}
for ( i=-3; i<=0; i++ ) for ( j=0; j<=3; j++ )
{
c = texture(InputTexture,coord+vec2(i,j)*bof).rgb;
m[1] += c;
s[1] += c*c;
}
for ( i=0; i<=3; i++ ) for ( j=-3; j<=0; j++ )
{
c = texture(InputTexture,coord+vec2(i,j)*bof).rgb;
m[2] += c;
s[2] += c*c;
}
for ( i=0; i<=3; i++ ) for ( j=0; j<=3; j++ )
{
c = texture(InputTexture,coord+vec2(i,j)*bof).rgb;
m[3] += c;
s[3] += c*c;
}
float min_sigma2 = 1e+2, sigma2;
for ( i=0; i<4; i++ )
{
m[i] /= n;
s[i] = abs(s[i]/n-m[i]*m[i]);
sigma2 = s[i].r+s[i].g+s[i].b;
if ( sigma2 >= min_sigma2 ) continue;
min_sigma2 = sigma2;
res.rgb = m[i];
}
FragColor = res;
}

View file

@ -0,0 +1,33 @@
/*
Paint filter from MariENB (second pass median smoothing)
(C)2012-2021 Marisa Kirisame
*/
#define luminance(x) dot(x,vec3(0.2126,0.7152,0.0722))
void main()
{
vec2 coord = TexCoord;
vec4 res = vec4(1.);
vec2 bresl = textureSize(InputTexture,0);
vec2 bof = 1./bresl;
vec3 m1, m2, m3;
vec3 a, b, c;
a = texture(InputTexture,coord+vec2(-1,-1)*bof).rgb;
b = texture(InputTexture,coord+vec2( 0,-1)*bof).rgb;
c = texture(InputTexture,coord+vec2( 1,-1)*bof).rgb;
m1 = (luminance(a)<luminance(b))?((luminance(b)<luminance(c))?b
:max(a,c)):((luminance(a)<luminance(c))?a:max(b,c));
a = texture(InputTexture,coord+vec2(-1, 0)*bof).rgb;
b = texture(InputTexture,coord+vec2( 0, 0)*bof).rgb;
c = texture(InputTexture,coord+vec2( 1, 0)*bof).rgb;
m2 = (luminance(a)<luminance(b))?((luminance(b)<luminance(c))?b
:max(a,c)):((luminance(a)<luminance(c))?a:max(b,c));
a = texture(InputTexture,coord+vec2(-1, 1)*bof).rgb;
b = texture(InputTexture,coord+vec2( 0, 1)*bof).rgb;
c = texture(InputTexture,coord+vec2( 1, 1)*bof).rgb;
m3 = (luminance(a)<luminance(b))?((luminance(b)<luminance(c))?b
:max(a,c)):((luminance(a)<luminance(c))?a:max(b,c));
res.rgb = (luminance(m1)<luminance(m2))?((luminance(m2)<luminance(m3))
?m2:max(m1,m3)):((luminance(m1)<luminance(m3))?m1:max(m2,m3));
FragColor = res;
}

View file

@ -0,0 +1,38 @@
/*
Paint filter from MariENB (third pass FXAA)
(C)2012-2021 Marisa Kirisame
*/
void main()
{
vec2 coord = TexCoord;
vec4 res = vec4(1.);
vec2 bresl = textureSize(InputTexture,0);
vec2 bof = 1./bresl;
float fxaareducemul = 1./16.;
float fxaareducemin = 1./128.;
float fxaaspanmax = 4.;
vec3 rgbNW = texture(InputTexture,coord+vec2(-1,-1)*bof).rgb;
vec3 rgbNE = texture(InputTexture,coord+vec2(1,-1)*bof).rgb;
vec3 rgbSW = texture(InputTexture,coord+vec2(-1,1)*bof).rgb;
vec3 rgbSE = texture(InputTexture,coord+vec2(1,1)*bof).rgb;
vec3 rgbM = texture(InputTexture,coord).rgb;
vec3 luma = vec3(.299,.587,.114);
float lumaNW = dot(rgbNW,luma);
float lumaNE = dot(rgbNE,luma);
float lumaSW = dot(rgbSW,luma);
float lumaSE = dot(rgbSE,luma);
float lumaM = dot(rgbM,luma);
float lumaMin = min(lumaM,min(min(lumaNW,lumaNE),min(lumaSW,lumaSE)));
float lumaMax = max(lumaM,max(max(lumaNW,lumaNE),max(lumaSW,lumaSE)));
vec2 dir = vec2(-((lumaNW+lumaNE)-(lumaSW+lumaSE)),((lumaNW+lumaSW)-(lumaNE+lumaSE)));
float dirReduce = max((lumaNW+lumaNE+lumaSW+lumaSE)*(.25*fxaareducemul),fxaareducemin);
float rcpDirMin = 1./(min(abs(dir.x),abs(dir.y))+dirReduce);
dir = min(vec2(fxaaspanmax,fxaaspanmax),max(vec2(-fxaaspanmax,-fxaaspanmax),dir*rcpDirMin))/bresl;
vec3 rgbA = (1./2.)*(texture(InputTexture,coord+dir*(1./3.-.5)).rgb+texture(InputTexture,coord+dir*(2./3.-.5)).rgb);
vec3 rgbB = rgbA*(1./2.)+(1./4.)*(texture(InputTexture,coord+dir*(0./3.-.5)).rgb+texture(InputTexture,coord+dir*(3./3.-.5)).rgb);
float lumaB = dot(rgbB,luma);
if ( (lumaB < lumaMin) || (lumaB > lumaMax) ) res.rgb = rgbA;
else res.rgb = rgbB;
FragColor = res;
}

View file

@ -202,8 +202,12 @@ Class MariFXHandler : StaticEventHandler
Shader.SetUniform1f(p,"mfx_lumasharp","sharpblend",mfx_lsharpblend);
// FILM GRAIN
Shader.SetEnabled(p,"mfx_grain",mfx_ne);
Shader.SetUniform1f(p,"mfx_grain","nf",mfx_nf/10.);
Shader.SetUniform1f(p,"mfx_grain","ni",mfx_ni);
Shader.SetUniform1f(p,"mfx_grain","ns",mfx_ns);
Shader.SetUniform3f(p,"mfx_grain","nm1",(mfx_nm1_r,mfx_nm1_g,mfx_nm1_b));
Shader.SetUniform1f(p,"mfx_grain","nk",mfx_nk);
Shader.SetUniform3f(p,"mfx_grain","nm2",(mfx_nm2_r,mfx_nm2_g,mfx_nm2_b));
Shader.SetUniform1f(p,"mfx_grain","np",mfx_np);
Shader.SetUniform1f(p,"mfx_grain","bnp",mfx_bnp);
Shader.SetUniform1i(p,"mfx_grain","nb",mfx_nb);
@ -283,6 +287,10 @@ Class MariFXHandler : StaticEventHandler
Shader.SetUniform1f(p,"mfx_vignette","vigbump",mfx_vigbump);
Shader.SetUniform1i(p,"mfx_vignette","vigshape",mfx_vigshape);
Shader.SetUniform1i(p,"mfx_vignette","vigmode",mfx_vigmode);
// PAINTING
Shader.SetEnabled(p,"mfx_paint_pass1",mfx_paintenable);
Shader.SetEnabled(p,"mfx_paint_pass2",mfx_paintenable);
Shader.SetEnabled(p,"mfx_paint_pass3",mfx_paintenable);
// RETRO FX
Vector2 rresl = (Screen.GetWidth(),Screen.GetHeight());
Vector2 bresl = rresl;
@ -330,8 +338,16 @@ Class MariFXHandler : StaticEventHandler
case 0:
CVar.FindCVar('mfx_ne').ResetToDefault();
CVar.FindCVar('mfx_ni').ResetToDefault();
CVar.FindCVar('mfx_nf').ResetToDefault();
CVar.FindCVar('mfx_ns').ResetToDefault();
CVar.FindCVar('mfx_np').ResetToDefault();
CVar.FindCVar('mfx_nm1_r').ResetToDefault();
CVar.FindCVar('mfx_nm1_g').ResetToDefault();
CVar.FindCVar('mfx_nm1_b').ResetToDefault();
CVar.FindCVar('mfx_nk').ResetToDefault();
CVar.FindCVar('mfx_nm2_r').ResetToDefault();
CVar.FindCVar('mfx_nm2_g').ResetToDefault();
CVar.FindCVar('mfx_nm2_b').ResetToDefault();
CVar.FindCVar('mfx_bnp').ResetToDefault();
CVar.FindCVar('mfx_nb').ResetToDefault();
break;
@ -447,6 +463,9 @@ Class MariFXHandler : StaticEventHandler
CVar.FindCVar('mfx_techenable').ResetToDefault();
CVar.FindCVar('mfx_techblend').ResetToDefault();
break;
case 11:
CVar.FindCVar('mfx_paintenable').ResetToDefault();
break;
}
}
}