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