Add "simplified" grain option, for extra performance.

Uses PRNG calls instead of texture fetches, so it tends to look more harsh and have patterning issues depending on the GPU.
This commit is contained in:
Marisa the Magician 2022-11-10 16:11:44 +01:00
commit 7efc84adb5
6 changed files with 105 additions and 19 deletions

View file

@ -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;

View file

@ -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
{

View file

@ -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";

View file

@ -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"

View file

@ -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;
}

View file

@ -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();