95 lines
2.8 KiB
Plaintext
95 lines
2.8 KiB
Plaintext
shader_type canvas_item;
|
|
|
|
const float HCV_EPSILON = 1e-10;
|
|
const float HSL_EPSILON = 1e-10;
|
|
|
|
uniform sampler2D screen_texture:
|
|
hint_screen_texture,
|
|
repeat_disable,
|
|
filter_linear_mipmap;
|
|
|
|
uniform sampler2D distortion:source_color;
|
|
uniform float distortionSpread : hint_range(0,0.08) = 0.05;
|
|
uniform float distortionOffset : hint_range(0,0.08) = 0.05;
|
|
uniform sampler2D lightnessCurve;
|
|
uniform sampler2D lightnessSaturationCurve;
|
|
|
|
uniform float saturationMultiply: hint_range(0,10) = 1;
|
|
uniform float effectStrength : hint_range(0,1) = 1;
|
|
|
|
uniform float vignetteStrength : hint_range(0,1) =1;
|
|
uniform float vignetteSize : hint_range(0.1,10)=1;
|
|
uniform float vignetteSmoothnes : hint_range(0.1,10) =1;
|
|
uniform vec4 vignetteColor = vec4(0,0,0,1);
|
|
uniform float vignetteOffset : hint_range(-1,1) =0.1;
|
|
|
|
|
|
vec3 RGBtoHCV( vec3 rgb )
|
|
{
|
|
vec4 P = (rgb.g < rgb.b) ? vec4(rgb.bg, -1.0, 2.0/3.0) : vec4(rgb.gb, 0.0, -1.0/3.0);
|
|
vec4 Q = (rgb.r < P.x) ? vec4(P.xyw, rgb.r) : vec4(rgb.r, P.yzx);
|
|
float C = Q.x - min(Q.w, Q.y);
|
|
float H = abs((Q.w - Q.y) / (6.0 * C + HCV_EPSILON) + Q.z);
|
|
return vec3(H, C, Q.x);
|
|
}
|
|
|
|
|
|
vec3 RGBtoHSL( vec3 rgb )
|
|
{
|
|
vec3 HCV = RGBtoHCV( rgb );
|
|
float L = HCV.z - HCV.y * 0.5;
|
|
float S = HCV.y / (1.0 - abs(L * 2.0 - 1.0) + HSL_EPSILON);
|
|
return vec3( HCV.x, S, L);
|
|
}
|
|
|
|
vec3 HuetoRGB( float hue )
|
|
{
|
|
float R = abs(hue * 6.0 - 3.0) - 1.0;
|
|
float G = 2.0 - abs(hue * 6.0 - 2.0);
|
|
float B = 2.0 - abs(hue * 6.0 - 4.0);
|
|
return clamp(vec3(R,G,B),0,1);
|
|
}
|
|
|
|
vec3 HSLtoRGB( vec3 hsl)
|
|
{
|
|
vec3 rgb = HuetoRGB( hsl.x );
|
|
float C = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;
|
|
return (rgb - 0.5) * C + hsl.z;
|
|
}
|
|
|
|
vec3 toLinear( vec3 sRGB )
|
|
{
|
|
return mix(pow((sRGB + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),sRGB * (1.0 / 12.92),lessThan(sRGB,vec3(0.04045)));
|
|
}
|
|
|
|
void fragment()
|
|
{
|
|
|
|
vec3 distortionValues = texture( distortion, UV ).rgb;
|
|
// distortionValues = toLinear( distortionValues );
|
|
|
|
distortionValues -= vec3( 0.5, 0.5, 0 );
|
|
vec2 seperation = vec2( distortionValues.z, 0 ) * distortionSpread;
|
|
vec2 uvDistortion = distortionValues.xy * distortionOffset;
|
|
vec2 uv = UV + uvDistortion;
|
|
float r = texture( screen_texture, uv - seperation ).r;
|
|
float g = texture( screen_texture, uv ).g;
|
|
float b = texture( screen_texture, uv + seperation ).b;
|
|
vec3 rgb = vec3( r, g, b);
|
|
vec3 hsl = RGBtoHSL( rgb );
|
|
|
|
float mappedLightness = texture( lightnessCurve, vec2(hsl.z,0) ).r;
|
|
hsl.z = mappedLightness;
|
|
float saturationOffset = texture( lightnessSaturationCurve, vec2(mappedLightness,0) ).r;
|
|
hsl.y = clamp( hsl.y + (saturationOffset - 0.5),0,1);
|
|
hsl.y = hsl.y * saturationMultiply;
|
|
rgb = mix( rgb, HSLtoRGB( hsl ), effectStrength ) ;
|
|
|
|
float d = ( max(0,vignetteOffset + length( UV - vec2(0.5,0.5 )) )) / vignetteSize;
|
|
d = pow( d, vignetteSmoothnes );
|
|
rgb = mix( rgb, vignetteColor.rgb * rgb, d * vignetteStrength );
|
|
COLOR = vec4( rgb, 1 );
|
|
|
|
}
|
|
|