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