diff --git a/cvarinfo.marifx b/cvarinfo.marifx index e4743f1..29786a6 100644 --- a/cvarinfo.marifx +++ b/cvarinfo.marifx @@ -6,6 +6,7 @@ nosave float mfx_lsharpclamp = .05; nosave float mfx_lsharpblend = 6.; nosave bool mfx_ne = false; +nosave bool mfx_nc = true; nosave float mfx_ni = .05; nosave float mfx_ns = 0.; nosave float mfx_nf = .05; diff --git a/gldefs.txt b/gldefs.txt index 865cef0..bfc0e9e 100644 --- a/gldefs.txt +++ b/gldefs.txt @@ -23,6 +23,18 @@ HardwareShader postprocess scene Uniform int nb Texture NoiseTexture "textures/mfxnoise.png" } +HardwareShader postprocess scene +{ + Name "mfx_grain_simple" + Shader "shaders/glsl/mfx_grain_simple.fp" 330 + Uniform float Timer + Uniform float nf + Uniform float ni + Uniform float ns + Uniform float np + Uniform float bnp + Uniform int nb +} HardwareShader postprocess scene { diff --git a/language.txt b/language.txt index 9f25075..38b22cd 100644 --- a/language.txt +++ b/language.txt @@ -118,6 +118,7 @@ MFX_LSHARPRADIUS="Sharpen Radius"; MFX_LSHARPTRESHOLD="Sharpen Threshold"; MFX_LSHARPSTRENGTH="Sharpen Strength"; MFX_GRAIN="Film Grain"; +MFX_GRAINALT="Simplified Grain"; MFX_NF="Grain Speed"; MFX_NI="Grain Intensity"; MFX_NS="Grain Saturation"; diff --git a/menudef.txt b/menudef.txt index 5115d9f..8051bed 100644 --- a/menudef.txt +++ b/menudef.txt @@ -163,17 +163,18 @@ OptionMenu "MFXOptionsMenu" StaticText "$MFX_GRAIN", 1 StaticText " " Option "$MFX_ENABLE", "mfx_ne", "YesNo" + Option "$MFX_GRAINALT", "mfx_nc", "NoYes" MFXSlider "$MFX_NI", "mfx_ni", 0, 1, 0.01, 2 - MFXSlider "$MFX_NF", "mfx_nf", -10, 10, 0.01, 2 + MFXSlider "$MFX_NF", "mfx_nf", -10, 10, 0.01, 2, "mfx_nc" MFXSlider "$MFX_NS", "mfx_ns", -1, 1, 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 + MFXSlider "$MFX_NM1_R", "mfx_nm1_r", 0, 10, 0.01, 2, "mfx_nc" + MFXSlider "$MFX_NM1_G", "mfx_nm1_g", 0, 10, 0.01, 2, "mfx_nc" + MFXSlider "$MFX_NM1_B", "mfx_nm1_b", 0, 10, 0.01, 2, "mfx_nc" + MFXSlider "$MFX_NK", "mfx_nk", 0, 1, 0.01, 2, "mfx_nc" + MFXSlider "$MFX_NM2_R", "mfx_nm2_r", 0, 10, 0.01, 2, "mfx_nc" + MFXSlider "$MFX_NM2_G", "mfx_nm2_g", 0, 10, 0.01, 2, "mfx_nc" + MFXSlider "$MFX_NM2_B", "mfx_nm2_b", 0, 10, 0.01, 2, "mfx_nc" Option "$MFX_NB", "mfx_nb", "MFXGrainBlend" MFXSlider "$MFX_BNP", "mfx_bnp", 0, 10, 0.01, 2 SafeCommand "$MFX_RESET", "event resetmfxvars 0" diff --git a/shaders/glsl/mfx_grain_simple.fp b/shaders/glsl/mfx_grain_simple.fp new file mode 100644 index 0000000..a6d71a4 --- /dev/null +++ b/shaders/glsl/mfx_grain_simple.fp @@ -0,0 +1,54 @@ +/* + Complex grain shader ported over from MariENB + This is a simplified version that uses three PRNG calls + (C)2012-2022 Marisa the Magician +*/ +#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)))) + +// simplified PRNG, for performance +float rnd( in vec2 sd ) +{ + return fract(sin(dot(sd,vec2(12.9898,78.233)))*43758.5453); +} + +vec3 grain( in vec3 res, in vec2 coord ) +{ + float ts = Timer; + vec2 s1 = coord+vec2(0.,ts); + vec2 s2 = coord+vec2(ts,0.); + vec2 s3 = coord+vec2(ts,ts); + float n1 = rnd(s1); + float n2 = rnd(s2); + float n3 = rnd(s3); + 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,1.),vec3(np)); + if ( nb == 1 ) res.rgb += nt*ni; + else if ( nb == 2 ) + { + 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 if ( nb == 3 ) + { + float bn = 1.-clamp((res.r+res.g+res.b)/3.,0.,1.); + bn = pow(bn,bnp); + 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; +} + +void main() +{ + vec2 coord = TexCoord; + vec4 res = texture(InputTexture,coord); + res.rgb = grain(res.rgb,coord); + FragColor = res; +} diff --git a/zscript/mfx_handler.zsc b/zscript/mfx_handler.zsc index ec278ac..9345037 100644 --- a/zscript/mfx_handler.zsc +++ b/zscript/mfx_handler.zsc @@ -10,6 +10,7 @@ Class MariFXHandler : StaticEventHandler { Shader.SetEnabled(p,"mfx_lumasharp",false); Shader.SetEnabled(p,"mfx_grain",false); + Shader.SetEnabled(p,"mfx_grain_simple",false); Shader.SetEnabled(p,"mfx_dirt",false); Shader.SetEnabled(p,"mfx_grading",false); Shader.SetEnabled(p,"mfx_lutgrading",false); @@ -34,17 +35,32 @@ Class MariFXHandler : StaticEventHandler Shader.SetUniform1f(p,"mfx_lumasharp","sharpclamp",mfx_lsharpclamp); 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); - Shader.SetUniform1f(p,"mfx_grain","Timer",(gametic+e.fractic)/35.); + if ( mfx_nc ) + { + Shader.SetEnabled(p,"mfx_grain",mfx_ne); + Shader.SetEnabled(p,"mfx_grain_simple",false); + 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); + Shader.SetUniform1f(p,"mfx_grain","Timer",(gametic+e.fractic)/35.); + } + else + { + Shader.SetEnabled(p,"mfx_grain",false); + Shader.SetEnabled(p,"mfx_grain_simple",mfx_ne); + Shader.SetUniform1f(p,"mfx_grain_simple","ni",mfx_ni); + Shader.SetUniform1f(p,"mfx_grain_simple","ns",mfx_ns); + Shader.SetUniform1f(p,"mfx_grain_simple","np",mfx_np); + Shader.SetUniform1f(p,"mfx_grain_simple","bnp",mfx_bnp); + Shader.SetUniform1i(p,"mfx_grain_simple","nb",mfx_nb); + Shader.SetUniform1f(p,"mfx_grain_simple","Timer",(gametic+e.fractic)/35.); + } // SCREEN DIRT Shader.SetEnabled(p,"mfx_dirt",mfx_dirtenable); Shader.SetUniform1f(p,"mfx_dirt","dirtmc",mfx_dirtmc); @@ -170,6 +186,7 @@ Class MariFXHandler : StaticEventHandler { case 0: CVar.FindCVar('mfx_ne').ResetToDefault(); + CVar.FindCVar('mfx_nc').ResetToDefault(); CVar.FindCVar('mfx_ni').ResetToDefault(); CVar.FindCVar('mfx_nf').ResetToDefault(); CVar.FindCVar('mfx_ns').ResetToDefault();