Gizmo199
Member
Horri-Fi is a simple and easy-to-use Shader for Game Maker Studio 2! Setup is as simple as calling:
Code:
horrifi_enable(true);
Code:
horrifi_set();
draw_surface(application_surface, 0, 0);
horrifi_reset();
This shader includes:
- Bloom
- Chromatic Abberation
- Scanlines
- VHS Distortion
- CRT TV Curve
- Noise
- Vignette
Code:
horrifi_*element_set()
Code:
horrifi_bloom_set()
horrifi_chromaticab_set()
horrifi_scanlines_set()
horrifi_vhs_set()
horrifi_vignette_set()
horrifi_crt_set()
horrifi_noise_set()
Don't wanna download anything? Below is the script library, fragment, and vertex shader you can easily copy/paste!
GML:
global.__horriFi =
{
#region Main System
enabled : true,
time : 0,
#endregion
#region Parameter Structs
// Vignette settings
vignette :
{
enabled : false,
strength : .25,
intensity : .5
},
// Noise settings
noise :
{
enabled : false,
strength : .1
},
// Chromatic abberation settings
chromatic_abberation :
{
enabled : false,
strength : .3
},
// Bloom
bloom :
{
enabled : false,
radius : 8,
intensity : 1,
threshold : 0.8
},
// VHS Distortion
vhs :
{
enabled : false,
strength : .5
},
// Scanlines
scanlines :
{
enabled : false,
strength : .25
},
// CRT Curve
crt :
{
enabled : false,
curve : 2
},
#endregion
#region Shader Uniforms
uniEnable : shader_get_uniform(shd_horrifi, "enable"),
uniTime : shader_get_uniform(shd_horrifi, "time"),
uniSeed : shader_get_uniform(shd_horrifi, "seed"),
uniTexel : shader_get_uniform(shd_horrifi, "texel"),
uniVig : shader_get_uniform(shd_horrifi, "vignette"),
uniNstr : shader_get_uniform(shd_horrifi, "noise_strength"),
uniChab : shader_get_uniform(shd_horrifi, "chab_intensity"),
uniBloom : shader_get_uniform(shd_horrifi, "bloom"),
uniScanStr : shader_get_uniform(shd_horrifi, "scan_strength"),
uniVhs : shader_get_uniform(shd_horrifi, "vhs_strength"),
uniCurve : shader_get_uniform(shd_horrifi, "curve"),
#endregion
#region Functions
render : function()
{
var _w, _h, _s;
_s = surface_get_texture(application_surface);
_w = texture_get_texel_width(_s);
_h = texture_get_texel_height(_s);
if ( !enabled ) exit;
// Set shader
shader_set(shd_horrifi);
// Enable effects
shader_set_uniform_f_array( uniEnable,
[
bloom.enabled,
chromatic_abberation.enabled,
noise.enabled,
vignette.enabled,
scanlines.enabled,
vhs.enabled,
crt.enabled
]
);
// Set effects parameters
shader_set_uniform_f(uniTexel, _w, _h);
shader_set_uniform_f(uniTime, time++);
shader_set_uniform_f(uniSeed, 1+random(100));
shader_set_uniform_f(uniVig, vignette.intensity, vignette.strength);
shader_set_uniform_f(uniNstr, noise.strength);
shader_set_uniform_f(uniChab, chromatic_abberation.strength);
shader_set_uniform_f(uniBloom, bloom.radius, bloom.intensity, bloom.threshold);
shader_set_uniform_f(uniScanStr, scanlines.strength);
shader_set_uniform_f(uniVhs, vhs.strength);
shader_set_uniform_f(uniCurve, crt.curve, crt.curve);
},
// Resetting
reset : function()
{
if ( enabled ) shader_reset();
}
#endregion
}
// Main functions
function horrifi_enable(onoff)
{
///@func horrifi_enable(enable)
global.__horriFi.enabled = onoff;
}
function horrifi_is_enabled()
{
return global.__horriFi.enabled;
}
function horrifi_set()
{
global.__horriFi.render();
}
function horrifi_reset()
{
global.__horriFi.reset();
}
// Bloom functions
function horrifi_bloom_enable(onoff)
{
///@func horrifi_bloom_enable(enable)
global.__horriFi.bloom.enabled = onoff;
}
function horrifi_bloom_radius(rad)
{
///@func horrifi_bloom_radius(radius)
global.__horriFi.bloom.radius = rad;
}
function horrifi_bloom_intensity(int)
{
///@func horrifi_bloom_intensity(intensity)
global.__horriFi.bloom.intensity = int;
}
function horrifi_bloom_threshold(thresh)
{
///@func horrifi_bloom_threshold(threshold)
global.__horriFi.bloom.threshold = thresh;
}
function horrifi_bloom_is_enabled()
{
return global.__horriFi.bloom.enabled;
}
function horrifi_bloom_get_radius()
{
return global.__horriFi.bloom.radius;
}
function horrifi_bloom_get_intensity()
{
return global.__horriFi.bloom.intensity;
}
function horrifi_bloom_get_threshold()
{
return global.__horriFi.bloom.threshold;
}
function horrifi_bloom_set(e,r,i,t)
{
///@func horrifi_bloom_set(enabled, radius, intensity, threshold)
horrifi_bloom_enable(e);
horrifi_bloom_radius(r);
horrifi_bloom_intensity(i);
horrifi_bloom_threshold(t);
}
// Chromatic Abberation functions
function horrifi_chromaticab_enable(onoff)
{
///@func horrifi_chromaticab_enable(enable)
global.__horriFi.chromatic_abberation.enabled = onoff;
}
function horrifi_chromaticab_strength(str)
{
///@func horrifi_chromaticab_strength(strength)
global.__horriFi.chromatic_abberation.strength = str;
}
function horrifi_chromaticab_is_enabled()
{
return global.__horriFi.chromatic_abberation.enabled;
}
function horrifi_chromaticab_get_strength()
{
return global.__horriFi.chromatic_abberation.strength;
}
function horrifi_chromaticab_set(e,s)
{
///@func horrifi_chromaticab_set(enable, strength)
horrifi_chromaticab_enable(e);
horrifi_chromaticab_strength(s);
}
// Noise functions
function horrifi_noise_enable(onoff)
{
///@func horrifi_noise_enable(enable)
global.__horriFi.noise.enabled = onoff;
}
function horrifi_noise_strength(str)
{
///@func horrifi_noise_strength(strength)
global.__horriFi.noise.strength = str;
}
function horrifi_noise_is_enabled()
{
return global.__horriFi.noise.enabled;
}
function horrifi_noise_get_strength()
{
return global.__horriFi.noise.strength;
}
function horrifi_noise_set(e, s)
{
///@func horrifi_noise_set(enable, strength)
horrifi_noise_enable(e);
horrifi_noise_strength(s);
}
// Vignette functions
function horrifi_vignette_enable(onoff)
{
///@func horrifi_vignette_enable(enable)
global.__horriFi.vignette.enabled=onoff
}
function horrifi_vignette_strength(str)
{
///@func horrifi_vignette_strength(strength)
global.__horriFi.vignette.strength = str;
}
function horrifi_vignette_intensity(int)
{
///@func horrifi_vignette_intensity(intensity)
global.__horriFi.vignette.intensity = int;
}
function horrifi_vignette_is_enabled()
{
return global.__horriFi.vignette.enabled;
}
function horrifi_vignette_get_strength()
{
return global.__horriFi.vignette.strength;
}
function horrifi_vignette_get_intensity()
{
return global.__horriFi.vignette.intensity;
}
function horrifi_vignette_set(e,s,i)
{
///@func horrifi_vignette_set(enable, strength, intensity)
horrifi_vignette_enable(e);
horrifi_vignette_strength(s);
horrifi_vignette_intensity(i);
}
// VHS functions
function horrifi_vhs_enable(onoff)
{
///@func horrifi_vhs_enable(enable)
global.__horriFi.vhs.enabled = onoff;
}
function horrifi_vhs_strength(str)
{
///@func horrifi_vhs_strength(strength)
global.__horriFi.vhs.strength = str;
}
function horrifi_vhs_is_enabled()
{
return global.__horriFi.vhs.enabled;
}
function horrifi_vhs_get_strength()
{
return global.__horriFi.vhs.strength;
}
function horrifi_vhs_set(e,s)
{
///@func horrifi_vhs_set(enable, strength)
horrifi_vhs_enable(e);
horrifi_vhs_strength(s);
}
// Scanlines functions
function horrifi_scanlines_enable(onoff)
{
///@func horrifi_scanlines_enable(enable)
global.__horriFi.scanlines.enabled = onoff;
}
function horrifi_scanlines_strength(str)
{
///@func horrifi_scanlines_strength(strength)
global.__horriFi.scanlines.strength = str;
}
function horrifi_scanlines_is_enabled()
{
return global.__horriFi.scanlines.enabled;
}
function horrifi_scanlines_get_strength()
{
return global.__horriFi.scanlines.strength;
}
function horrifi_scanlines_set(e,s)
{
///@func horrifi_scanlines_set(enable, strength)
horrifi_scanlines_enable(e);
horrifi_scanlines_strength(s);
}
// CRT functions
function horrifi_crt_enable(onoff)
{
///@func horrifi_crt_enable(enable)
global.__horriFi.crt.enabled = onoff;
}
function horrifi_crt_curve(str1)
{
///@func horrifi_crt_curve(strength)
global.__horriFi.crt.curve = str1;
}
function horrifi_crt_is_enabled()
{
return global.__horriFi.crt.enabled;
}
function horrifi_crt_get_curve()
{
return global.__horriFi.crt.curve;
}
function horrifi_crt_set(e,s1)
{
///@func horrifi_crt_set(enable, curve)
horrifi_crt_enable(e);
horrifi_crt_curve(s1);
}
Code:
attribute vec3 in_Position; // (x,y,z)
attribute vec4 in_Colour; // (r,g,b,a)
attribute vec2 in_TextureCoord; // (u,v)
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
void main()
{
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
v_vColour = in_Colour;
v_vTexcoord = in_TextureCoord;
}
Code:
#define SAMPLES 32.
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform float enable[7];
uniform float time;
uniform float seed;
uniform float noise_strength;
uniform float chab_intensity;
uniform float vhs_strength;
uniform float scan_strength;
uniform vec2 curve;
uniform vec2 texel;
uniform vec2 vignette;
uniform vec3 bloom;
// Noise
float noise(vec2 uv)
{
return fract(sin(uv.x*12.9898+uv.y*78.233)*437.585453*seed);
}
// VHS
vec4 vhs(vec2 uv)
{
vec2 tcoord = uv;
tcoord.x += sin(time*noise(uv));
return texture2D( gm_BaseTexture, tcoord)*vhs_strength;
}
// Vignette
float vig(vec2 uv)
{
uv *= 1. - uv;
return ( pow(uv.x*uv.y*vignette.x*10.,vignette.y) );
}
// Chromatic abberation
vec3 chromatic(vec2 uv, float offset)
{
float _r = texture2D( gm_BaseTexture, vec2(uv.x+offset, uv.y)).r;
float _g = texture2D( gm_BaseTexture, uv).g;
float _b = texture2D( gm_BaseTexture, vec2(uv.x-offset, uv.y)).b;
return vec3(_r,_g,_b);
}
// Bloom
vec4 blur(vec2 uv)
{
float total = 0.;
float rad = 1.;
mat2 ang = mat2(.73736882209777832,-.67549037933349609,.67549037933349609,.73736882209777832);
vec2 point = normalize(fract(cos(uv*mat2(195,174,286,183))*742.)-.5)*(bloom.x/sqrt(SAMPLES));
vec4 amount = vec4(0);
for ( float i=0.; i<SAMPLES; i++ )
{
point*=ang;
rad+=1./rad;
vec4 samp = texture2D(gm_BaseTexture, uv + point * (rad-1.) * texel);
float mul = 1.;
float lum = ( samp.r+samp.g+samp.b )/3.;
if ( lum < bloom.z ){ mul = 0.; }
amount += samp*(1./rad)*mul;
total+=(1./rad);
}
amount /= total;
return amount*bloom.y;
}
// TV Curve
vec2 crt_curve( vec2 uv )
{
uv = uv*2.-1.;
vec2 uvoff = abs(uv.xy) / vec2(curve.x, curve.y);
uv = uv + uv * uvoff * uvoff;
uv = uv * .5 + .5;
return uv;
}
void main()
{
// CRT
vec2 mainUv = v_vTexcoord;
if ( enable[6] > .5 ) mainUv = crt_curve(v_vTexcoord);
// Base coloring
vec4 color = v_vColour * texture2D( gm_BaseTexture, mainUv);
// Chromatic abberation
if ( enable[1] > .5 ) color.rgb = v_vColour.rgb * chromatic(mainUv, chab_intensity * 0.01);
// Scanlines
if ( enable[4] > .5 ) color.rgb *= (1.-scan_strength)+(sin(mainUv.y*1024.)*scan_strength);
// Bloom
if ( enable[0] > .5 ) color.rgb += blur(mainUv).rgb;
// Noise
if ( enable[2] > .5 ) color.rgb += noise(mainUv)*noise_strength;
// VHS
if ( enable[5] > .5 ) color += vhs(mainUv);
// Vignette
if ( enable[3] > .5) color.rgb *= vig(mainUv);
// Cutoff edges
if ( enable[6] > .5)
{
if ( mainUv.x<0.||mainUv.y<0.||mainUv.x>1.||mainUv.y>1. )
{
color.rgb *= 0.;
}
}
gl_FragColor = color;
}
Last edited: