/*===============================================================================*\|####################### [FINAL FANTASY 7 SHADER FX] ########################||######################### By Sunwalker 21/Jan/2017 ##########################||| Version 1.05 |||| |||| This program is free software; you can redistribute it and/or |||| modify it under the terms of the GNU General Public License |||| as published by the Free Software Foundation; either version 2 |||| of the License, or (at your option) any later version. |||| |||| This program is distributed in the hope that it will be useful, |||| but WITHOUT ANY WARRANTY; without even the implied warranty of |||| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |||| GNU General Public License for more details. (c)2016 |||| |||#################################################################################|\*===============================================================================*/#version 120 #extension GL_NV_gpu_shader5 : enable#extension GL_ARB_gpu_shader5 : enable#extension GL_ARB_shader_precision : enable#extension GL_ARB_sample_shading : enable#extension GL_ARB_texture_rectangle : enable#extension GL_ARB_shader_storage_buffer_object : enable#extension GL_ARB_shader_image_load_store : enable#extension GL_ARB_bindless_texture : enable#extension GL_ARB_shading_language_420pack : enable/*------------------------------------------------------------------------------[DEFINITIONS & ON/OFF OPTIONS]------------------------------------------------------------------------------*///--------------------------#[CHOOSE EFFECTS]#--------------------------------\\//#[ANTIALIASING TECHNIQUES] [1=ON|0=OFF] # NOTE: #define USE_FXAA 0 //# [0 or 1] FXAA Fast Anti-aliasing//#[LIGHTING & COLOUR] [1=ON|0=OFF] # NOTE: This one can enable all#define GAMMA_CORRECTION 0 //# RGB Gamma Correction. Fixed expansion to variable compression gamma correction curve.#define BLENDED_BLOOM 0 //# High Quality SP Bloom. Soft lighting with blending techniques, for a natural looking bloom.#define SCENE_TONEMAPPING 0 //# HDR Scene Tonemapping. Layered component conversion, and applies scene tone mapping.#define COLOR_CORRECTION 0 //# Component Color Correction. Colorspace conversion, with correction curves, and multiple palette types.#define CROSS_PROCESSING 0 //# Filmic Cross Processing. Alters the tone of the scene, crossing the game's color set, with another.#define PIXEL_VIBRANCE 0 //# Pixel Vibrance. Intelligently adjusts pixel vibrance depending on original color saturation.#define COLOR_GRADING 0 //# Post-Complement Colour Grading. Alters individual colour components on a scene, to enhance selected colour tones.#define USE_CURVES 0 //# [0 or 1] Curves : Contrast adjustments using S-curves.//#[MISC] [1=ON|0=OFF] # NOTE: Enable one only#define NTSC_TV_EMULATION 1 //# SimoneT's TV Colors Emulation Shader. Use to emulate the original PSX color space tone, and vibrancy./*------------------------------------------------------------------------------[EFFECT CONFIG OPTIONS]------------------------------------------------------------------------------*///##[GAMMA_CORRECTION]#define Gamma 2.40 //[1.5 to 4.0] Gamma correction. Decrease for lower gamma(darker). Increase for higher gamma(brighter). (Default: 2.2)//##[BLENDED_BLOOM]#define BloomType BlendScreen //[BlendGlow, BlendAddGlow, BlendAddLight, BlendScreen, BlendLuma, BlendOverlay] The type of blended bloom. Light<->Dark.#define BloomStrength 0.200 //[0.000 to 1.000] Overall strength of the bloom. You may want to readjust for each blend type.#define BlendStrength 1.000 //[0.000 to 1.000] Strength of the blending. This is a modifier based on bloom. 1.0 equates to 100% strength.#define BloomDefocus 2.000 //[1.000 to 4.000] The initial bloom defocus value. Increases the softness of light, bright objects, etc.#define BloomWidth 3.200 //[1.000 to 8.000] Width of the bloom. Adjusts the width of the spread and soft glow. Scales with BloomStrength.#define BloomReds 0.040 //[0.000 to 1.000] Red channel correction of the bloom. Raising will increase the bloom of reds.#define BloomGreens 0.030 //[0.000 to 1.000] Green channel correction of the bloom. Raising will increase the bloom of greens.#define BloomBlues 0.020 //[0.000 to 1.000] Blue channel correction of the bloom. Raising will increase the bloom of blues.//##[SCENE_TONEMAPPING]#define TonemapType 2 //[0|1|2|3] The base tone mapping operator. 0 is LDR, 1 is HDR(original), 2 & 3 are Filmic HDR(slight grading).#define TonemapMask 1 //[0 or 1] Enables an ALU tone masking curve. Produces a nice cinematic look. Suits some games more than others.#define MaskStrength 0.10 //[0.000 to 1.000] Strength of the tone masking. Higher for a stronger effect. This is a dependency of TonemapMask.#define ToneAmount 0.360 //[0.050 to 1.000] Tonemap strength (tone correction). Higher for stronger tone mapping, lower for lighter.#define BlackLevels 0.060 //[0.000 to 1.000] Black level balance (shadow correction). Increase to deepen blacks, lower to lighten them.#define Exposure 1.000 //[0.100 to 2.000] White correction (brightness). Higher values for more scene exposure, lower for less.#define Luminance 1.000 //[0.100 to 2.000] Luminance average (luminance correction). Higher values will lower scene luminance average.#define WhitePoint 1.075 //[0.100 to 2.000] Whitepoint average (wp lum correction). Higher values will lower the maximum scene white point.//##[COLOR_CORRECTION]#define CorrectionPalette 1 //[1|2|3|4|5] The colorspace palette type. 1: RGB, 2: YXY, 3: XYZ, 4: HSV, 5: YUV. Each one will produce a different combination of shades & hues.#define ChannelR 1.40 //[0.00 to 8.00] R(1), Y(2), X(3), H(4), Y(5) component channel varies with the colorspace used. Higher values increase correction strength.#define ChannelG 1.60 //[0.00 to 8.00] G(1), X(2), Y(3), S(4), U(5) component channel varies with the colorspace used. Higher values increase correction strength.#define ChannelB 1.80 //[0.00 to 8.00] B(1), Y(2), Z(3), V(4), V(5) component channel varies with the colorspace used. Higher values increase correction strength.#define PaletteStrength 2.00 //[0.00 to 4.00] The interpolated strength ratio between the base color, and the corrected color. Raise to increase saturation.//##[PIXEL_VIBRANCE]#define Vibrance 0.15 //[-1.00 to 1.00] Overall vibrance strength. Locally adjusts the vibrance of pixels depending on their original saturation.#define RedVibrance 1.00 //[-8.00 to 8.00] Red channel coefficient of the vibrance strength. Adjusting the vibrance of the red channel independently.#define GreenVibrance 1.00 //[-8.00 to 8.00] Green channel coefficient of the vibrance strength. Adjusting the vibrance of the green channel independently.#define BlueVibrance 1.00 //[-8.00 to 8.00] Blue channel coefficient of the vibrance strength. Adjusting the vibrance of the blue channel independently.//##[CROSS_PROCESSING]#define FilmicProcess 1 //[1|2|3] The color conversion type for the cross process. 1: cool, 2: warm, 3: dusk. You can achieve different results with each.#define RedShift 0.65 //[0.10 to 1.00] Red color component shift of the filmic processing. Alters the red balance of the shift.#define GreenShift 0.50 //[0.10 to 1.00] Green color component shift of the filmic processing. Alters the green balance of the shift.#define BlueShift 0.50 //[0.10 to 1.00] Blue color component shift of the filmic processing. Alters the blue balance of the shift.#define ShiftRatio 0.50 //[0.10 to 2.00] The blending ratio for the base color and the color shift. Higher for a stronger effect.//##[COLOR_GRADING]#define RedGrading 1.20 //[0.00 to 3.00] Red colour grading coefficient. Adjust to influence the red channel coefficients of the grading, and highlight tones.#define GreenGrading 1.10 //[0.00 to 3.00] Green colour grading coefficient. Adjust to influence the Green channel coefficients of the grading, and highlight tones.#define BlueGrading 1.10 //[0.00 to 3.00] Blue colour grading coefficient. Adjust to influence the Blue channel coefficients of the grading, and highlight tones.#define GradingStrength 0.35 //[0.00 to 1.00] The overall max strength of the colour grading effect. Raise to increase, lower to decrease the amount.#define Correlation 1.00 //[0.10 to 1.00] Correlation between the base colour, and the grading influence. Lower = more of the scene is graded, Higher = less of the scene is graded.//##[USE_CURVES]#define Curves_mode 2 //[0|1|2] Choose what to apply contrast to. 0 = Luma, 1 = Chroma, 2 = both Luma and Chroma. Default is 0 (Luma)#define Curves_contrast 0.30 //[-1.00 to 1.00] The amount of contrast you want//##[Advanced curve settings]#define Curves_formula 3 //[1|2|3|4|5|6|7|8|9|10] The contrast s-curve you want to use. //1 = Sine, 2 = Abs split, 3 = Smoothstep, 4 = Exp formula, 5 = Simplified Catmull-Rom (0,0,1,1), 6 = Perlins Smootherstep //7 = Abs add, 8 = Techicolor Cinestyle, 9 = Parabola, 10 = Half-circles. //Note that Technicolor Cinestyle is practically identical to Sine, but runs slower. In fact I think the difference might only be due to rounding errors. //I prefer 2 myself, but 3 is a nice alternative with a little more effect (but harsher on the highlight and shadows) and it's the fastest formula//[END OF USER OPTIONS]/*------------------------------------------------------------------------------[GLOBALS|FUNCTIONS]------------------------------------------------------------------------------*///Global variables#define saturate(x) clamp(x, 0.0, 1.0)#define lerp mix#define frac fract#define fmod mod#define mul(x, y) (y * x)#define float4x3 mat4x3#define float3x3 mat3#define float4x4 mat4#define lumCoeff vec3(0.212656, 0.715158, 0.072186)#define PI 3.1415972//OGL Uniformsuniform sampler2D OGLTexture;uniform sampler2D OGLTexture0;//varyinguniform vec2 texcoord;float Epsilon = 1e-10;#define texture_width 1024.0#define texture_height 1024.0#define texel_size_x (1.0 / texture_width) #define texel_size_y (1.0 / texture_height)#define OGLSize vec2(texture_width, texture_height)#define OGLInvSize vec2(texel_size_x, texel_size_y)//Average Relative Luminance (HSP Color Model)float AvgLuminance(vec3 color){ return sqrt(dot(color * color, lumCoeff));}//Smoothstep altfloat smootherstep(float a, float b, float x){ x = saturate((x - a) / (b - a)); return x*x*x*(x*(x * 6 - 15) + 10);}//Conversion matricesvec3 RGBtoXYZ(vec3 RGB){ const mat3 RGBtoXYZ = mat3( 0.6068909, 0.1735011, 0.2003480, 0.2989164, 0.5865990, 0.1144845, 0.0000000, 0.0660957, 1.1162243); return RGBtoXYZ*RGB;}vec3 XYZtoRGB(vec3 XYZ){ const mat3 XYZtoRGB = mat3( 1.9099961, -0.5324542, -0.2882091, -0.9846663, 1.9991710, -0.0283082, 0.0583056, -0.1183781, 0.8975535); return XYZtoRGB*XYZ;}vec3 XYZtoSRGB(vec3 XYZ){ const mat3 XYZtoSRGB = mat3( 3.2404542, -1.5371385, -0.4985314, -0.9692660, 1.8760108, 0.0415560, 0.0556434, -0.2040259, 1.0572252); return XYZtoSRGB*XYZ;}vec3 RGBtoYUV(vec3 RGB){ const mat3 RGBtoYUV = mat3( 0.2126, 0.7152, 0.0722, -0.09991, -0.33609, 0.436, 0.615, -0.55861, -0.05639); return RGBtoYUV*RGB;}vec3 YUVtoRGB(vec3 YUV){ const mat3 YUVtoRGB = mat3( 1.000, 0.000, 1.28033, 1.000, -0.21482, -0.38059, 1.000, 2.12798, 0.000); return YUVtoRGB*YUV;}vec3 XYZtoYxy(vec3 XYZ){ float w = (XYZ.r + XYZ.g + XYZ.b); vec3 Yxy; Yxy.r = XYZ.g; Yxy.g = XYZ.r / w; Yxy.b = XYZ.g / w; return Yxy;}vec3 YxytoXYZ(vec3 Yxy){ vec3 XYZ; XYZ.g = Yxy.r; XYZ.r = Yxy.r * Yxy.g / Yxy.b; XYZ.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b; return XYZ;}/*------------------------------------------------------------------------------[FXAA CODE SECTION]Code from http://www.geeks3d.com/20110405/fxaa-fast-approximate-anti-aliasing-demo-glsl-opengl-test-radeon-geforce/3/Credit to original Author------------------------------------------------------------------------------*/#if USE_FXAA == 1float xbrthreshold = 0.020;vec2 rcpFrame = OGLInvSize;vec3 FXAA(sampler2D OGLTexture, vec2 texcoord){ float FXAA_SPAN_MAX = 8.0; //[4.0 t0 8.0] float FXAA_REDUCE_MUL = (1.0 / FXAA_SPAN_MAX); //[Default] float FXAA_REDUCE_MIN = (1.0 / 128.0); //[Default] float FXAA_SUBPIX_SHIFT = (1.0 / 4.0); //[Default] vec4 posPos = vec4(texcoord.xy, texcoord.xy - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT))); /*---------------------------------------------------------*/ vec3 rgbNW = texture2D(OGLTexture, posPos.zw, 0.0).rgb; vec3 rgbNE = texture2D(OGLTexture, posPos.zw + vec2(1., 0.)*rcpFrame.xy, 0.0).rgb; vec3 rgbSW = texture2D(OGLTexture, posPos.zw + vec2(0., 1.)*rcpFrame.xy, 0.0).rgb; vec3 rgbSE = texture2D(OGLTexture, posPos.zw + vec2(1., 1.)*rcpFrame.xy, 0.0).rgb; vec3 rgbM = texture2D(OGLTexture, texcoord.xy, 0.0).rgb; /*---------------------------------------------------------*/ //vec3 luma = vec3(0.299, 0.587, 0.114); float lumaNW = AvgLuminance(rgbNW); float lumaNE = AvgLuminance(rgbNE); float lumaSW = AvgLuminance(rgbSW); float lumaSE = AvgLuminance(rgbSE); float lumaM = AvgLuminance(rgbM); /*---------------------------------------------------------*/ float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); /*---------------------------------------------------------*/ vec2 dir; dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); /*---------------------------------------------------------*/ float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * rcpFrame.xy; /*--------------------------------------------------------*/ vec3 rgbA = (1.0 / 2.0) * (texture2D(OGLTexture, texcoord.xy + dir * (1.0 / 3.0 - 0.5)).rgb + texture2D(OGLTexture, texcoord.xy + dir * (2.0 / 3.0 - 0.5)).rgb); vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * (texture2D(OGLTexture, texcoord.xy + dir * (0.0 / 3.0 - 0.5)).rgb + texture2D(OGLTexture, texcoord.xy + dir * (3.0 / 3.0 - 0.5)).rgb); float lumaB = AvgLuminance(rgbB); return ((lumaB < lumaMin) || (lumaB > lumaMax)) ? rgbA.rgb : rgbB.rgb;}//Hyllian's xBR Level 2 shader//Copyright(C) 2011 / 2014 Hyllian / Jararaca - [email protected]//Credit to Hyllianfloat x_Width = texture_width;float y_Height = texture_height;float x_coef = texel_size_x;float y_coef = texel_size_y;float coef = 2.0;vec3 rgbw = vec3(14.352, 28.176, 5.472);float x = 0.5 * (1.0 / x_Width);float y = 0.5 * (1.0 / y_Height);//vec2 dx = vec2(x, 0.0);//vec2 dy = vec2(0.0, y);vec2 dx = vec2(0.0009765625, 0.0);//vec2(x, 0.0);//vec2 dy = vec2(0.0, 0.001953125);//vec2(0.0, y);//vec2 x2 = vec2(0.001953125, 0.0);//vec2(y, 0);//vec2 y2 = vec2(0.0, 0.00390625);//vec2( 0.0 , y*2.0 );//vec4 xy = vec4(0.0009765625, 0.001953125, -0.0009765625, -0.001953125);//vec4( x, y,-x,-y);//vec4 zw = vec4(0.001953125, 0.001953125, -0.001953125, -0.00390625);//vec4( y , y,-y ,-(y*2.0));//vec4 wz = vec4(0.0009765625, 0.00390625, -0.0009765625, -0.00390625); //vec4( x, y*2.0 ,-x,-(y*2.0));//vec4 df(vec4 A, vec4 B){ return abs(A - B);}vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h){ return (df(a, b) + df(a, c) + df(d, e) + df(d, f) + 4.0*df(g, h));}vec3 xBR(sampler2D OGLTexture, vec2 texcoord) { vec4 edr, edr_left, edr_up; bvec4 px; // px = pixel, edr = edge detection rule vec4 interp_restriction_lv1, interp_restriction_lv2_left, interp_restriction_lv2_up; bvec4 nc; // new_color vec4 fx, fx_left, fx_up; // inequations of straight lines. vec2 fp = fract(texcoord.xy*vec2(x_Width, y_Height)); vec2 vTex = texcoord.xy - fp*vec2(0.0009765625*x_coef, 0.001953125*y_coef);//vec2(x, y); vec3 A = texture2D(OGLTexture, vTex + xy.zw).rgb; vec3 B = texture2D(OGLTexture, vTex - dy).rgb; vec3 C = texture2D(OGLTexture, vTex + xy.xw).rgb; vec3 D = texture2D(OGLTexture, vTex - dx).rgb; vec3 E = texture2D(OGLTexture, vTex).rgb; vec3 F = texture2D(OGLTexture, vTex + dx).rgb; vec3 G = texture2D(OGLTexture, vTex + xy.zy).rgb; vec3 H = texture2D(OGLTexture, vTex + dy).rgb; vec3 I = texture2D(OGLTexture, vTex + xy.xy).rgb; vec3 A1 = texture2D(OGLTexture, vTex + wz.zw).rgb; vec3 C1 = texture2D(OGLTexture, vTex + wz.xw).rgb; vec3 A0 = texture2D(OGLTexture, vTex + zw.zw).rgb; vec3 G0 = texture2D(OGLTexture, vTex + zw.zy).rgb; vec3 C4 = texture2D(OGLTexture, vTex + zw.xw).rgb; vec3 I4 = texture2D(OGLTexture, vTex + zw.xy).rgb; vec3 G5 = texture2D(OGLTexture, vTex + wz.zy).rgb; vec3 I5 = texture2D(OGLTexture, vTex + wz.xy).rgb; vec3 B1 = texture2D(OGLTexture, vTex - y2).rgb; vec3 D0 = texture2D(OGLTexture, vTex - x2).rgb; vec3 H5 = texture2D(OGLTexture, vTex + y2).rgb; vec3 F4 = texture2D(OGLTexture, vTex + x2).rgb; vec4 b = vec4(dot(B, rgbw), dot(D, rgbw), dot(H, rgbw), dot(F, rgbw)); vec4 c = vec4(dot(C, rgbw), dot(A, rgbw), dot(G, rgbw), dot(I, rgbw)); vec4 d = b.yzwx; vec4 e = vec4(dot(E, rgbw)); vec4 f = b.wxyz; vec4 g = c.zwxy; vec4 h = b.zwxy; vec4 i = c.wxyz; vec4 i4 = vec4(dot(I4, rgbw), dot(C1, rgbw), dot(A0, rgbw), dot(G5, rgbw)); vec4 i5 = vec4(dot(I5, rgbw), dot(C4, rgbw), dot(A1, rgbw), dot(G0, rgbw)); vec4 h5 = vec4(dot(H5, rgbw), dot(F4, rgbw), dot(B1, rgbw), dot(D0, rgbw)); vec4 f4 = h5.yzwx; vec4 Ao = vec4(1.0, -1.0, -1.0, 1.0); vec4 Bo = vec4(1.0, 1.0, -1.0, -1.0); vec4 Co = vec4(1.5, 0.5, -0.5, 0.5); vec4 Ax = vec4(1.0, -1.0, -1.0, 1.0); vec4 Bx = vec4(0.5, 2.0, -0.5, -2.0); vec4 Cx = vec4(1.0, 1.0, -0.5, 0.0); vec4 Ay = vec4(1.0, -1.0, -1.0, 1.0); vec4 By = vec4(2.0, 0.5, -2.0, -0.5); vec4 Cy = vec4(2.0, 0.0, -1.0, 0.5); vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25); // These inequations define the line below which interpolation occurs. fx = vec4(greaterThan(Ao*fp.y + Bo*fp.x, Co)); fx_left = vec4(greaterThan(Ax*fp.y + Bx*fp.x, Cx)); fx_up = vec4(greaterThan(Ay*fp.y + By*fp.x, Cy)); interp_restriction_lv1 = vec4(notEqual(e, f))*vec4(notEqual(e, h)); interp_restriction_lv2_left = vec4(notEqual(e, g))*vec4(notEqual(d, g)); interp_restriction_lv2_up = vec4(notEqual(e, c))*vec4(notEqual(b, c)); edr = vec4(lessThan(weighted_distance(e, c, g, i, h5, f4, h, f), weighted_distance(h, d, i5, f, i4, b, e, i)))*interp_restriction_lv1; edr_left = vec4(lessThanEqual(coef*df(f, g), df(h, c)))*interp_restriction_lv2_left; edr_up = vec4(greaterThanEqual(df(f, g), coef*df(h, c)))*interp_restriction_lv2_up; nc = bvec4(edr*(max(max(fx, edr_left*fx_left), edr_up*fx_up))); px = lessThanEqual(df(e, f), df(e, h)); vec3 res = nc.x ? px.x ? F : H : nc.y ? px.y ? B : F : nc.z ? px.z ? D : B : nc.w ? px.w ? H : D : E; return res;}float diff2D(vec2 coord){ vec3 dt = vec3(1.0, 1.0, 1.0); vec3 c00 = texture2D(OGLTexture, coord + 0.25*(-dx - dy)).xyz; vec3 c20 = texture2D(OGLTexture, coord + 0.25*(dx - dy)).xyz; vec3 c02 = texture2D(OGLTexture, coord + 0.25*(-dx + dy)).xyz; vec3 c22 = texture2D(OGLTexture, coord + 0.25*(dx + dy)).xyz; vec3 mn = min(min(c00, c20), min(c02, c22)); vec3 mx = max(max(c00, c20), max(c02, c22)); return dot(mx - mn, dt);}vec4 FXAAPass(vec4 color, vec2 texcoord){ vec2 fp = fract(texcoord * OGLSize); vec2 vTex = texcoord - fp * OGLInvSize + 0.5 * OGLInvSize; vec2 locator = sign(fp - vec2(0.5000000001, 0.5000000001)); float maxdiff = max(max(diff2D(vTex + locator*dx), diff2D(vTex + locator*dy)), diff2D(vTex)); if (maxdiff <= xbrthreshold) { color.rgb = xBR(OGLTexture, texcoord); } else { color.rgb = FXAA(OGLTexture, texcoord); } color.a = AvgLuminance(color.rgb); return color;}#endif/*------------------------------------------------------------------------------[GAMMA CORRECTION CODE SECTION]------------------------------------------------------------------------------*/vec3 EncodeGamma(vec3 color, float gamma){ color = saturate(color); color.r = (color.r <= 0.0404482362771082) ? color.r / 12.92 : pow((color.r + 0.055) / 1.055, gamma); color.g = (color.g <= 0.0404482362771082) ? color.g / 12.92 : pow((color.g + 0.055) / 1.055, gamma); color.b = (color.b <= 0.0404482362771082) ? color.b / 12.92 : pow((color.b + 0.055) / 1.055, gamma); return color;}vec3 DecodeGamma(vec3 color, float gamma){ color = saturate(color); color.r = (color.r <= 0.00313066844250063) ? color.r * 12.92 : 1.055 * pow(color.r, 1.0 / gamma) - 0.055; color.g = (color.g <= 0.00313066844250063) ? color.g * 12.92 : 1.055 * pow(color.g, 1.0 / gamma) - 0.055; color.b = (color.b <= 0.00313066844250063) ? color.b * 12.92 : 1.055 * pow(color.b, 1.0 / gamma) - 0.055; return color;}#if GAMMA_CORRECTION == 1vec4 GammaPass(vec4 color, vec2 texcoord){ const float GammaConst = 2.233333; color.rgb = EncodeGamma(color.rgb, GammaConst); color.rgb = DecodeGamma(color.rgb, float(Gamma)); color.a = AvgLuminance(color.rgb); return color;}#endif/*------------------------------------------------------------------------------[PIXEL VIBRANCE CODE SECTION]------------------------------------------------------------------------------*/#if PIXEL_VIBRANCE == 1vec4 VibrancePass(vec4 color, vec2 texcoord){ float vib = Vibrance; float lum = AvgLuminance(color.rgb); vec3 luma = vec3(lum, lum, lum); float colorMax = max(color.r, max(color.g, color.b)); float colorMin = min(color.r, min(color.g, color.b)); float colorSaturation = colorMax - colorMin; vec3 colorCoeff = vec3(RedVibrance * vib, GreenVibrance * vib, BlueVibrance * vib); color.rgb = lerp(luma, color.rgb, (1.0 + (colorCoeff * (1.0 - (sign(colorCoeff) * colorSaturation))))); color.a = AvgLuminance(color.rgb); return saturate(color); //Debug: return colorSaturation.xxxx;}#endif/*------------------------------------------------------------------------------[BLENDED BLOOM CODE SECTION]------------------------------------------------------------------------------*/#if BLENDED_BLOOM == 1vec3 BlendAddLight(vec3 bloom, vec3 blend){ return saturate(bloom + blend);}vec3 BlendScreen(vec3 bloom, vec3 blend){ return (bloom + blend) - (bloom * blend);}vec3 BlendGlow(vec3 bloom, vec3 blend){ float glow = AvgLuminance(bloom); return lerp((bloom + blend) - (bloom * blend), (blend + blend) - (blend * blend), glow);}vec3 BlendAddGlow(vec3 bloom, vec3 blend){ float addglow = smootherstep(0.0, 1.0, AvgLuminance(bloom)); return lerp(saturate(bloom + blend), (blend + blend) - (blend * blend), addglow);}vec3 BlendLuma(vec3 bloom, vec3 blend){ float lumavg = smootherstep(0.0, 1.0, AvgLuminance(bloom + blend)); return lerp((bloom * blend), (1.0 - ((1.0 - bloom) * (1.0 - blend))), lumavg);}vec3 BlendOverlay(vec3 bloom, vec3 blend){ vec3 overlay = step(0.5, bloom); return lerp((bloom * blend * 2.0), (1.0 - (2.0 *(1.0 - bloom) * (1.0 - blend))), overlay);}vec3 BloomCorrection(vec3 color){ vec3 bloom = color; bloom.r = 2.0 / 3.0 * (1.0 - (bloom.r * bloom.r)); bloom.g = 2.0 / 3.0 * (1.0 - (bloom.g * bloom.g)); bloom.b = 2.0 / 3.0 * (1.0 - (bloom.b * bloom.b)); bloom.r = saturate(color.r + float(BloomReds) * bloom.r); bloom.g = saturate(color.g + float(BloomGreens) * bloom.g); bloom.b = saturate(color.b + float(BloomBlues) * bloom.b); color = bloom; return color;}vec4 DefocusFilter(sampler2D OGLTexture, vec2 texcoord, vec2 defocus){ defocus = clamp(defocus, 1.0, 1.5); vec2 texel = vec2(texel_size_x, texel_size_y) * defocus; vec4 sampleA = texture2D(OGLTexture, texcoord + vec2(0.5, 0.5) * texel); vec4 sampleB = texture2D(OGLTexture, texcoord + vec2(-0.5, 0.5) * texel); vec4 sampleC = texture2D(OGLTexture, texcoord + vec2(0.5, -0.5) * texel); vec4 sampleD = texture2D(OGLTexture, texcoord + vec2(-0.5, -0.5) * texel); float fx = frac(texcoord.x * texture_width); float fy = frac(texcoord.y * texture_height); vec4 interpolateA = lerp(sampleA, sampleB, fx); vec4 interpolateB = lerp(sampleC, sampleD, fx); return lerp(interpolateA, interpolateB, fy);}vec4 BloomPass(vec4 color, vec2 texcoord){ float anflare = 4.0; float width = BloomWidth; vec2 defocus = vec2(BloomDefocus, BloomDefocus); vec4 bloom = DefocusFilter(OGLTexture, texcoord, defocus); vec2 dx = vec2(texel_size_x * width, 0.0); vec2 dy = vec2(0.0, texel_size_y * width); vec2 mdx = vec2(dx.x * defocus.x, 0.0); vec2 mdy = vec2(0.0, dy.y * defocus.y); vec4 blend = bloom * 0.22520613262190495; blend += 0.002589001911021066 * texture2D(OGLTexture, texcoord - mdx + mdy); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord - dx + mdy); blend += 0.024146616900339800 * texture2D(OGLTexture, texcoord + mdy); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord + dx + mdy); blend += 0.002589001911021066 * texture2D(OGLTexture, texcoord + mdx + mdy); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord - mdx + dy); blend += 0.044875475183061630 * texture2D(OGLTexture, texcoord - dx + dy); blend += 0.100529757860782610 * texture2D(OGLTexture, texcoord + dy); blend += 0.044875475183061630 * texture2D(OGLTexture, texcoord + dx + dy); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord + mdx + dy); blend += 0.024146616900339800 * texture2D(OGLTexture, texcoord - mdx); blend += 0.100529757860782610 * texture2D(OGLTexture, texcoord - dx); blend += 0.100529757860782610 * texture2D(OGLTexture, texcoord + dx); blend += 0.024146616900339800 * texture2D(OGLTexture, texcoord + mdx); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord - mdx - dy); blend += 0.044875475183061630 * texture2D(OGLTexture, texcoord - dx - dy); blend += 0.100529757860782610 * texture2D(OGLTexture, texcoord - dy); blend += 0.044875475183061630 * texture2D(OGLTexture, texcoord + dx - dy); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord + mdx - dy); blend += 0.002589001911021066 * texture2D(OGLTexture, texcoord - mdx - mdy); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord - dx - mdy); blend += 0.024146616900339800 * texture2D(OGLTexture, texcoord - mdy); blend += 0.010778807494659370 * texture2D(OGLTexture, texcoord + dx - mdy); blend += 0.002589001911021066 * texture2D(OGLTexture, texcoord + mdx - mdy); blend = lerp(color, blend, float(BlendStrength)); bloom.xyz = BloomType(bloom.xyz, blend.xyz); bloom.xyz = BloomCorrection(bloom.xyz); color.w = AvgLuminance(color.xyz); bloom.w = AvgLuminance(bloom.xyz); bloom.w *= anflare; color = lerp(color, bloom, float(BloomStrength)); return color;}#endif/*------------------------------------------------------------------------------[SCENE TONE MAPPING CODE SECTION]------------------------------------------------------------------------------*/#if SCENE_TONEMAPPING == 1vec3 ScaleLuminance(vec3 x){ float W = 1.02; // WhitePoint Scale float L = 0.16; // Luminance Scale float C = 1.02; // Compression Scale float N = clamp(0.82 + ToneAmount, 1.0, 2.0); float K = (N - L * C) / C; vec3 tone = L * C + (1.0 - L * C) * (1.0 + K * (x - L) / ((W - L) * (W - L))) * (x - L) / (x - L + K); vec3 color; color.r = (x.r > L) ? tone.r : C * x.r; color.g = (x.g > L) ? tone.g : C * x.g; color.b = (x.b > L) ? tone.b : C * x.b; return color;}vec3 TmMask(vec3 color){ vec3 tone = color; float highTone = 6.2; float greyTone = 0.4; float midTone = 1.62; float lowTone = 0.06; tone.r = (tone.r * (highTone * tone.r + greyTone)) / (tone.r * (highTone * tone.r + midTone) + lowTone); tone.g = (tone.g * (highTone * tone.g + greyTone)) / (tone.g * (highTone * tone.g + midTone) + lowTone); tone.b = (tone.b * (highTone * tone.b + greyTone)) / (tone.b * (highTone * tone.b + midTone) + lowTone); const float gamma = 2.42; tone = EncodeGamma(tone, gamma); color = lerp(color, tone, float(MaskStrength)); return color;}vec3 TmCurve(vec3 color){ vec3 T = color; float tnamn = ToneAmount; float blevel = length(T); float bmask = pow(blevel, 0.02); float A = 0.100; float B = 0.300; float C = 0.100; float D = tnamn; float E = 0.020; float F = 0.300; float W = 1.000; T.r = ((T.r*(A*T.r + C*B) + D*E) / (T.r*(A*T.r + B) + D*F)) - E / F; T.g = ((T.g*(A*T.g + C*B) + D*E) / (T.g*(A*T.g + B) + D*F)) - E / F; T.b = ((T.b*(A*T.b + C*B) + D*E) / (T.b*(A*T.b + B) + D*F)) - E / F; float denom = ((W*(A*W + C*B) + D*E) / (W*(A*W + B) + D*F)) - E / F; vec3 black = vec3(bmask, bmask, bmask); vec3 white = vec3(denom, denom, denom); T = T / white; T = T * black; color = saturate(T); return color;}vec4 TonemapPass(vec4 color, vec2 texcoord){ float L = Luminance; vec3 tonemap = color.rgb; vec3 luma = vec3(L, L, L); float blackLevel = length(tonemap); tonemap = ScaleLuminance(tonemap); float luminanceAverage = AvgLuminance(luma); if (TonemapMask == 1) { tonemap = TmMask(tonemap); } if (TonemapType == 1) { tonemap = TmCurve(tonemap); } // RGB -> XYZ conversion vec3 XYZ = RGBtoXYZ(tonemap); // XYZ -> Yxy conversion vec3 Yxy; Yxy.r = XYZ.g; // copy luminance Y Yxy.g = XYZ.r / (XYZ.r + XYZ.g + XYZ.b); // x = X / (X + Y + Z) Yxy.b = XYZ.g / (XYZ.r + XYZ.g + XYZ.b); // y = Y / (X + Y + Z) // (Wt) Tone mapped scaling of the initial wp before input modifiers float Wt = saturate(Yxy.r / AvgLuminance(XYZ)); if (TonemapType == 2) { Yxy.r = TmCurve(Yxy).r; } // (Lp) Map average luminance to the middlegrey zone by scaling pixel luminance float Lp = Yxy.r * float(Exposure) / (luminanceAverage + Epsilon); // (Wp) White point calculated, based on the toned white, and input modifier float Wp = dot(abs(Wt), float(WhitePoint)); // (Ld) Scale all luminance within a displayable range of 0 to 1 Yxy.r = (Lp * (1.0 + Lp / (Wp * Wp))) / (1.0 + Lp); // Yxy -> XYZ conversion XYZ.r = Yxy.r * Yxy.g / Yxy.b; // X = Y * x / y XYZ.g = Yxy.r; // copy luminance Y XYZ.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b; // Z = Y * (1-x-y) / y if (TonemapType == 3) { XYZ = TmCurve(XYZ); } // XYZ -> RGB conversion tonemap = XYZtoRGB(XYZ); float shadowmask = pow(saturate(blackLevel), float(BlackLevels)); tonemap = tonemap * vec3(shadowmask, shadowmask, shadowmask); color.rgb = tonemap; color.a = AvgLuminance(color.rgb); return color;}#endif/*------------------------------------------------------------------------------[COLOR CORRECTION CODE SECTION]------------------------------------------------------------------------------*/// Converting pure hue to RGBvec3 HUEtoRGB(float H){ float R = abs(H * 6.0 - 3.0) - 1.0; float G = 2.0 - abs(H * 6.0 - 2.0); float B = 2.0 - abs(H * 6.0 - 4.0); return saturate(vec3(R, G, B));}// Converting RGB to hue/chroma/valuevec3 RGBtoHCV(vec3 RGB){ vec4 BG = vec4(RGB.bg, -1.0, 2.0 / 3.0); vec4 GB = vec4(RGB.gb, 0.0, -1.0 / 3.0); vec4 P = (RGB.g < RGB.b) ? BG : GB; vec4 XY = vec4(P.xyw, RGB.r); vec4 YZ = vec4(RGB.r, P.yzx); vec4 Q = (RGB.r < P.x) ? XY : YZ; float C = Q.x - min(Q.w, Q.y); float H = abs((Q.w - Q.y) / (6.0 * C + Epsilon) + Q.z); return vec3(H, C, Q.x);}// Converting RGB to HSVvec3 RGBtoHSV(vec3 RGB){ vec3 HCV = RGBtoHCV(RGB); float S = HCV.y / (HCV.z + Epsilon); return vec3(HCV.x, S, HCV.z);}// Converting HSV to RGBvec3 HSVtoRGB(vec3 HSV){ vec3 RGB = HUEtoRGB(HSV.x); return ((RGB - 1.0) * HSV.y + 1.0) * HSV.z;}#if COLOR_CORRECTION == 1// Pre correction color maskvec3 PreCorrection(vec3 color){ vec3 RGB = color; RGB.r = 2.0 / 3.0 * (1.0 - (RGB.r * RGB.r)); RGB.g = 2.0 / 3.0 * (1.0 - (RGB.g * RGB.g)); RGB.b = 2.0 / 3.0 * (1.0 - (RGB.b * RGB.b)); RGB.r = saturate(color.r + (float(ChannelR) / 200.0) * RGB.r); RGB.g = saturate(color.g + (float(ChannelG) / 200.0) * RGB.g); RGB.b = saturate(color.b + (float(ChannelB) / 200.0) * RGB.b); color = saturate(RGB); return color;}vec3 ColorCorrection(vec3 color){ float X = 1.0 / (1.0 + exp(float(ChannelR) / 2.0)); float Y = 1.0 / (1.0 + exp(float(ChannelG) / 2.0)); float Z = 1.0 / (1.0 + exp(float(ChannelB) / 2.0)); color.r = (1.0 / (1.0 + exp(float(-ChannelR) * (color.r - 0.5))) - X) / (1.0 - 2.0 * X); color.g = (1.0 / (1.0 + exp(float(-ChannelG) * (color.g - 0.5))) - Y) / (1.0 - 2.0 * Y); color.b = (1.0 / (1.0 + exp(float(-ChannelB) * (color.b - 0.5))) - Z) / (1.0 - 2.0 * Z); return saturate(color);}vec4 CorrectionPass(vec4 color, vec2 texcoord){ vec3 colorspace = PreCorrection(color.rgb);#if CorrectionPalette == 1 colorspace = ColorCorrection(colorspace);#elif CorrectionPalette == 2 vec3 XYZ = RGBtoXYZ(colorspace); vec3 Yxy = XYZtoYxy(XYZ); Yxy = ColorCorrection(Yxy); XYZ = YxytoXYZ(Yxy); colorspace = XYZtoRGB(XYZ);#elif CorrectionPalette == 3 vec3 XYZ = RGBtoXYZ(colorspace); vec3 Yxy = XYZtoYxy(XYZ); XYZ = YxytoXYZ(Yxy); XYZ = ColorCorrection(XYZ); colorspace = XYZtoRGB(XYZ);#elif CorrectionPalette == 4 vec3 hsv = RGBtoHSV(colorspace); hsv = ColorCorrection(hsv); colorspace = HSVtoRGB(hsv);#elif CorrectionPalette == 5 vec3 yuv = RGBtoYUV(colorspace); yuv = ColorCorrection(yuv); colorspace = YUVtoRGB(yuv);#endif color.rgb = lerp(color.rgb, colorspace, float(PaletteStrength)); color.a = AvgLuminance(color.rgb); return color;}#endif/*------------------------------------------------------------------------------[S-CURVE CONTRAST CODE SECTION]------------------------------------------------------------------------------*/#if USE_CURVES == 1vec4 CurvesPass(vec4 color, vec2 texcoord){ float Curves_contrast_blend = Curves_contrast; /*-----------------------------------------------------------. / Separation of Luma and Chroma / '-----------------------------------------------------------*/ // -- Calculate Luma and Chroma if needed --#if Curves_mode != 2 //calculate luma (grey) float luma = dot(lumCoeff, color.rgb); //calculate chroma vec3 chroma = color.rgb - luma;#endif // -- Which value to put through the contrast formula? -- // I name it x because makes it easier to copy-paste to Graphtoy or Wolfram Alpha or another graphing program#if Curves_mode == 2 vec3 x = color.rgb; //if the curve should be applied to both Luma and Chroma#elif Curves_mode == 1 vec3 x = chroma; //if the curve should be applied to Chroma x = x * 0.5 + 0.5; //adjust range of Chroma from -1 -> 1 to 0 -> 1#else // Curves_mode == 0 float x = luma; //if the curve should be applied to Luma#endif // Contrast formulas // -- Curve 1 --#if Curves_formula == 1 x = sin(PI * 0.5 * x); // Sin - 721 amd fps, +vign 536 nv x *= x; //x = 0.5 - 0.5*cos(PI*x); //x = 0.5 * -sin(PI * -x + (PI*0.5)) + 0.5;#endif // -- Curve 2 --#if Curves_formula == 2 x = x - 0.5; x = (x / (0.5 + abs(x))) + 0.5; //x = ( (x - 0.5) / (0.5 + abs(x-0.5)) ) + 0.5;#endif // -- Curve 3 --#if Curves_formula == 3 //x = smoothstep(0.0,1.0,x); //smoothstep x = x*x*(3.0 - 2.0*x); //faster smoothstep alternative - 776 amd fps, +vign 536 nv //x = x - 2.0 * (x - 1.0) * x* (x- 0.5); //2.0 is contrast. Range is 0.0 to 2.0#endif // -- Curve 4 --#if Curves_formula == 4 x = (1.0524 * exp(6.0 * x) - 1.05248) / (20.0855 + exp(6.0 * x)); //exp formula#endif // -- Curve 5 --#if Curves_formula == 5 //x = 0.5 * (x + 3.0 * x * x - 2.0 * x * x * x); //a simplified catmull-rom (0,0,1,1) - btw smoothstep can also be expressed as a simplified catmull-rom using (1,0,1,0) //x = (0.5 * x) + (1.5 -x) * x*x; //estrin form - faster version x = x * (x * (1.5 - x) + 0.5); //horner form - fastest version Curves_contrast_blend = Curves_contrast * 2.0; //I multiply by two to give it a strength closer to the other curves.#endif // -- Curve 6 --#if Curves_formula == 6 x = x*x*x*(x*(x*6.0 - 15.0) + 10.0); //Perlins smootherstep#endif // -- Curve 7 --#if Curves_formula == 7 //x = ((x-0.5) / ((0.5/(4.0/3.0)) + abs((x-0.5)*1.25))) + 0.5; x = x - 0.5; x = x / ((abs(x)*1.25) + 0.375) + 0.5; //x = ( (x-0.5) / ((abs(x-0.5)*1.25) + (0.5/(4.0/3.0))) ) + 0.5;#endif // -- Curve 8 --#if Curves_formula == 8 x = (x * (x * (x * (x * (x * (x * (1.6 * x - 7.2) + 10.8) - 4.2) - 3.6) + 2.7) - 1.8) + 2.7) * x * x; //Techicolor Cinestyle - almost identical to curve 1#endif // -- Curve 9 --#if Curves_formula == 9 x = -0.5 * (x*2.0 - 1.0) * (abs(x*2.0 - 1.0) - 2.0) + 0.5; //parabola#endif // -- Curve 10 --#if Curves_formula == 10 //Half-circles#if Curves_mode == 0 float xstep = step(x, 0.5); float xstep_shift = (xstep - 0.5); float shifted_x = x + xstep_shift;#else vec3 xstep = step(x, 0.5); vec3 xstep_shift = (xstep - 0.5); vec3 shifted_x = x + xstep_shift;#endif x = abs(xstep - sqrt(-shifted_x * shifted_x + shifted_x)) - xstep_shift; //x = abs(step(x,0.5)-sqrt(-(x+step(x,0.5)-0.5)*(x+step(x,0.5)-0.5)+(x+step(x,0.5)-0.5)))-(step(x,0.5)-0.5); //single line version of the above //x = 0.5 + (sign(x-0.5)) * sqrt(0.25-(x-trunc(x*2))*(x-trunc(x*2))); //worse /* // if/else - even worse if (x-0.5) x = 0.5-sqrt(0.25-x*x); else x = 0.5+sqrt(0.25-(x-1)*(x-1)); */ //x = (abs(step(0.5,x)-clamp( 1-sqrt(1-abs(step(0.5,x)- frac(x*2%1)) * abs(step(0.5,x)- frac(x*2%1))),0 ,1))+ step(0.5,x) )*0.5; //worst so far //TODO: Check if I could use an abs split instead of step. It might be more efficient Curves_contrast_blend = Curves_contrast * 0.5; //I divide by two to give it a strength closer to the other curves.#endif // -- Curve 11 --#if Curves_formula == 11 //Cubic catmull float a = 1.00; //control point 1 float b = 0.00; //start point float c = 1.00; //endpoint float d = 0.20; //control point 2 x = 0.5 * ((-a + 3 * b - 3 * c + d)*x*x*x + (2 * a - 5 * b + 4 * c - d)*x*x + (-a + c)*x + 2 * b); //A customizable cubic catmull-rom spline#endif // -- Curve 12 --#if Curves_formula == 12 //Cubic Bezier spline float a = 0.00; //start point float b = 0.00; //control point 1 float c = 1.00; //control point 2 float d = 1.00; //endpoint float r = (1 - x); float r2 = r*r; float r3 = r2 * r; float x2 = x*x; float x3 = x2*x; //x = dot(float4(a,b,c,d),float4(r3,3*r2*x,3*r*x2,x3)); //x = a * r*r*r + r * (3 * b * r * x + 3 * c * x*x) + d * x*x*x; //x = a*(1-x)*(1-x)*(1-x) +(1-x) * (3*b * (1-x) * x + 3 * c * x*x) + d * x*x*x; x = a*(1 - x)*(1 - x)*(1 - x) + 3 * b*(1 - x)*(1 - x)*x + 3 * c*(1 - x)*x*x + d*x*x*x;#endif // -- Curve 13 --#if Curves_formula == 13 //Cubic Bezier spline - alternative implementation. vec3 a = vec3(0.00, 0.00, 0.00); //start point vec3 b = vec3(0.25, 0.15, 0.85); //control point 1 vec3 c = vec3(0.75, 0.85, 0.15); //control point 2 vec3 d = vec3(1.00, 1.00, 1.00); //endpoint vec3 ab = lerp(a, b, x); // point between a and b vec3 bc = lerp(b, c, x); // point between b and c vec3 cd = lerp(c, d, x); // point between c and d vec3 abbc = lerp(ab, bc, x); // point between ab and bc vec3 bccd = lerp(bc, cd, x); // point between bc and cd vec3 dest = lerp(abbc, bccd, x); // point on the bezier-curve x = dest;#endif // -- Curve 14 --#if Curves_formula == 14 x = 1.0 / (1.0 + exp(-(x * 10.0 - 5.0))); //alternative exp formula#endif //Joining of Luma and Chroma #if Curves_mode == 2 //Both Luma and Chroma vec3 col = x; //if the curve should be applied to both Luma and Chroma color.rgb = lerp(color.rgb, col, Curves_contrast_blend); //Blend by Curves_contrast#elif Curves_mode == 1 //Only Chroma x = x * 2.0 - 1.0; //adjust the Chroma range back to -1 -> 1 vec3 col = luma + x; //Luma + Chroma color.rgb = lerp(color.rgb, col, Curves_contrast_blend); //Blend by Curves_contrast#else // Curves_mode == 0 //Only Luma x = lerp(luma, x, Curves_contrast_blend); //Blend by Curves_contrast color.rgb = x + chroma; //Luma + Chroma#endif //Return the result color.a = AvgLuminance(color.rgb); return saturate(color);}#endif/*------------------------------------------------------------------------------[CROSS PROCESSING CODE SECTION]------------------------------------------------------------------------------*/#if CROSS_PROCESSING == 1vec3 CrossShift(vec3 color){ vec3 cross; vec2 CrossMatrix[3] = vec2[]( vec2(0.960, 0.040 * color.x), vec2(0.980, 0.020 * color.y), vec2(0.970, 0.030 * color.z)); cross.x = float(RedShift) * CrossMatrix[0].x + CrossMatrix[0].y; cross.y = float(GreenShift) * CrossMatrix[1].x + CrossMatrix[1].y; cross.z = float(BlueShift) * CrossMatrix[2].x + CrossMatrix[2].y; float lum = AvgLuminance(color); vec3 black = vec3(0.0, 0.0, 0.0); vec3 white = vec3(1.0, 1.0, 1.0); cross = lerp(black, cross, saturate(lum * 2.0)); cross = lerp(cross, white, saturate(lum - 0.5) * 2.0); color = lerp(color, cross, saturate(lum * float(ShiftRatio))); return color;}vec4 CrossPass(vec4 color, vec2 texcoord){#if FilmicProcess == 1 color.rgb = CrossShift(color.rgb);#elif FilmicProcess == 2 vec3 XYZ = RGBtoXYZ(color.rgb); vec3 Yxy = XYZtoYxy(XYZ); Yxy = CrossShift(Yxy); XYZ = YxytoXYZ(Yxy); color.rgb = XYZtoRGB(XYZ);#elif FilmicProcess == 3 vec3 XYZ = RGBtoXYZ(color.rgb); vec3 Yxy = XYZtoYxy(XYZ); XYZ = YxytoXYZ(Yxy); XYZ = CrossShift(XYZ); color.rgb = XYZtoRGB(XYZ);#endif color.a = AvgLuminance(color.rgb); return saturate(color);}#endif/*------------------------------------------------------------------------------[COLOR GRADING CODE SECTION]------------------------------------------------------------------------------*/#if COLOR_GRADING == 1float RGBCVtoHUE(vec3 RGB, float C, float V){ vec3 Delta = (V - RGB) / C; Delta.rgb -= Delta.brg; Delta.rgb += vec3(2.0, 4.0, 6.0); Delta.brg = step(V, RGB) * Delta.brg; float H; H = max(Delta.r, max(Delta.g, Delta.b)); return frac(H / 6);}vec3 HSVComplement(vec3 HSV){ vec3 complement = HSV; complement.x -= 0.5; if (complement.x < 0.0) { complement.x += 1.0; } return(complement);}float HueLerp(float h1, float h2, float v){ float d = abs(h1 - h2); if (d <= 0.5) { return lerp(h1, h2, v); } else if (h1 < h2) { return frac(lerp((h1 + 1.0), h2, v)); } else { return frac(lerp(h1, (h2 + 1.0), v)); }}vec4 ColorGradingPass(vec4 color, vec2 texcoord){ vec3 guide = vec3(RedGrading, GreenGrading, BlueGrading); float amount = GradingStrength; float correlation = Correlation; float concentration = 2.00; vec3 colorHSV = RGBtoHSV(color.rgb); vec3 huePoleA = RGBtoHSV(guide); vec3 huePoleB = HSVComplement(huePoleA); float dist1 = abs(colorHSV.x - huePoleA.x); if (dist1 > 0.5) dist1 = 1.0 - dist1; float dist2 = abs(colorHSV.x - huePoleB.x); if (dist2 > 0.5) dist2 = 1.0 - dist2; float descent = smoothstep(0.0, correlation, colorHSV.y); vec3 HSVColor = colorHSV; if (dist1 < dist2) { float c = descent * amount * (1.0 - pow((dist1 * 2.0), 1.0 / concentration)); HSVColor.x = HueLerp(colorHSV.x, huePoleA.x, c); HSVColor.y = lerp(colorHSV.y, huePoleA.y, c); } else { float c = descent * amount * (1.0 - pow((dist2 * 2.0), 1.0 / concentration)); HSVColor.x = HueLerp(colorHSV.x, huePoleB.x, c); HSVColor.y = lerp(colorHSV.y, huePoleB.y, c); } color.rgb = HSVtoRGB(HSVColor); color.a = AvgLuminance(color.rgb); return saturate(color);}#endif/*------------------------------------------------------------------------------[TV COLORS EMU CODE SECTION]------------------------------------------------------------------------------*//*------------------------------------------------------------------------------SimoneT NTSC TV colors emulation 1.0 ShaderCopyright (C) 2016 SimoneT - [email protected]Credit to SimoneT.------------------------------------------------------------------------------*/#if NTSC_TV_EMULATION == 1// conversion from NTSC RGB Reference White D65 ( color space used by NA/Japan TV's ) to XYZvec3 NTSC(vec3 c){ vec3 v = vec3(pow(c.r, 2.2), pow(c.g, 2.2), pow(c.b, 2.2)); //Inverse Companding return v*mat3( 0.6068909, 0.1735011, 0.2003480, 0.2989164, 0.5865990, 0.1144845, 0.0000000, 0.0660957, 1.1162243);}// conversion from XYZ to sRGB Reference White D65 ( color space used by windows ) vec3 sRGB(vec3 c){ vec3 v = c*mat3( 3.2404542, -1.5371385, -0.4985314, -0.9692660, 1.8760108, 0.0415560, 0.0556434, -0.2040259, 1.0572252); //Companding v.r = (v.r > 0.0031308) ? ((1.055 * pow(v.r, (1.0 / 2.4))) - 0.055) : 12.92 * v.r; v.g = (v.g > 0.0031308) ? ((1.055 * pow(v.g, (1.0 / 2.4))) - 0.055) : 12.92 * v.g; v.b = (v.b > 0.0031308) ? ((1.055 * pow(v.b, (1.0 / 2.4))) - 0.055) : 12.92 * v.b; return v;}// NTSC RGB to sRGBvec3 NTSCtoSRGB(vec3 c){ return sRGB(NTSC(c));}// Ported from SimoneT TV colors emulation 1.0 Shadervec4 TvColorsPass(vec4 color, vec2 texcoord){ color.rgb = NTSCtoSRGB(color.rgb); return color;}#endif/*------------------------------------------------------------------------------[MAIN() & COMBINE PASS CODE SECTION]------------------------------------------------------------------------------*/void main(){ vec2 texcoord = gl_TexCoord[0].xy; vec4 color = texture2D(OGLTexture0, texcoord);#if USE_FXAA == 1 color = FXAAPass(color, texcoord);#endif#if GAMMA_CORRECTION == 1 color = GammaPass(color, texcoord);#endif#if PIXEL_VIBRANCE == 1 color = VibrancePass(color, texcoord);#endif#if BLENDED_BLOOM == 1 color = BloomPass(color, texcoord);#endif#if SCENE_TONEMAPPING == 1 color = TonemapPass(color, texcoord);#endif#if USE_CURVES == 1 color = CurvesPass(color, texcoord);#endif#if COLOR_CORRECTION == 1 color = CorrectionPass(color, texcoord);#endif#if CROSS_PROCESSING == 1 color = CrossPass(color, texcoord);#endif #if COLOR_GRADING == 1 color = ColorGradingPass(color, texcoord);#endif#if NTSC_TV_EMULATION == 1 color = TvColorsPass(color, texcoord);#endif gl_FragColor = color;}