#version 420 #extension GL_ARB_texture_gather : enable // Adjustable Bloom + Tone Mapping + Adjustable Vibrance(Contrasty) /*=============================Settings=====================================*/ #define adjust_bloom 1 // 0: disable, 1: enable. const float bloomFactor = 0.7; // 1.0 is neutral #define tone_mapping 0 // -1: disable, clamp bright detail but keep [0,1] intact, however clamping could lead to desaturation as well // 0: (Wii U) BotW original // 1: ACES Filmic //--------------------"ACES Filmic" Parameters-----------------// const float Exposure = 0.6; // [0.0, 1.0+] Adjust exposure //---------------------------------------------------------------// #define post_process 2 // -1: disable // 0: (Wii U) BotW original, only vibrance // 1: Reshade Vibrance // 2: Contrasty // 3: Experimental, convert rgb to hsv then adjust saturation directly //----------------"BotW original" vibrance adjust-------------// const float satFactor = 0.29; // 0.18 is neutral. Experimental, adjust native saturation //---------------------------------------------------------------// //-----------------"Reshade Vibrance" Parameters--------------// const float Vibrance = 0.40; // Saturates (or desaturates if you use negative values) the pixels depending on their original saturation. const vec3 VibranceRGBBalance = vec3(1.0,1.0,1.0); // A per channel multiplier to the Vibrance strength so you can give more boost to certain colors over others. //---------------------------------------------------------------// //---------------------"Contrasty" Parameters-----------------// const float gamma = 0.81; // 1.0 is neutral. Botw is already colour graded at this stage const float exposure = 1.17; // 1.0 is neutral const float vibrance = 0.45; // 0.0 is neutral const float crushContrast = 0.004; // 0.0 is neutral. Use small increments, loss of shadow detail //---------------------------------------------------------------// //------------------------"hsv experiment"---------------------// const float satScale = 1.5; // 1.0 is neutral //---------------------------------------------------------------// /*==========================================================================*/ // shader bd8bba59e2149449 // bloom(add), tonemap, saturate uniform ivec4 uf_remappedPS[1]; layout(binding = 0) uniform sampler2D textureUnitPS0; //bloom layout(binding = 1) uniform sampler2D textureUnitPS1; //texture, hdr layout(location = 0) in vec4 passParameterSem0; layout(location = 0) out vec4 passPixelColor0; uniform vec2 uf_fragCoordScale; float getL601(vec3 rgb) { return dot(rgb,vec3(0.2989,0.5866,0.1145)); } float getL709(vec3 rgb) { return dot(rgb,vec3(0.2126,0.7152,0.0722)); } vec3 BotWToneMap(vec3 color) { float Lumn = getL601(color); vec4 exptm = 1.0 - exp(-vec4(color,Lumn)); vec3 cpre = exptm.w / Lumn * color; vec3 colorldr = mix(cpre,exptm.rgb,vec3(pow(exptm.w,2.0)));//refine return colorldr; } vec3 ACESFilm(vec3 color) { color *= Exposure; return (color*(2.51*color+0.03))/(color*(2.43*color+0.59)+0.14); } vec3 BotWVibrance(vec3 color) { float avg = (color.r + color.g + color.b)/3.0; float maxc = max(color.r, max(color.g,color.b)); float w = 1.0 - pow(1.0 - 2.0 * avg, 2.0); float weight = 1.0 + w * satFactor; vec3 satcolor = mix(vec3(maxc), color, weight); return satcolor; } vec3 ReshadeVibrance(vec3 color) { float max_color = max(color.r, max(color.g, color.b)); // Find the strongest color float min_color = min(color.r, min(color.g, color.b)); // Find the weakest color float luma = getL709(color); float color_saturation = max_color - min_color; // The difference between the two is the saturation vec3 coeffVibrance = VibranceRGBBalance * Vibrance; color = mix(vec3(luma), color, 1.0 + (coeffVibrance * (1.0 - (sign(coeffVibrance) * color_saturation)))); return color; } vec3 Contrasty(vec3 fColour) { fColour = max(vec3(0.0), fColour - vec3(crushContrast)); fColour = clamp(exposure * fColour, 0.0, 1.0); fColour = pow(fColour, vec3(1.0 / gamma)); float luminance = getL601(fColour); float mn = min(min(fColour.r, fColour.g), fColour.b); float mx = max(max(fColour.r, fColour.g), fColour.b); float sat = (1.0-(mx - mn)) * (1.0-mx) * luminance * 5.0; vec3 lightness = vec3((mn + mx)/2.0); // vibrance fColour = mix(fColour, mix(fColour, lightness, -vibrance), sat); return fColour; } vec3 rgb2hsv(vec3 c) { vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } vec3 hsv2rgb(vec3 c) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } vec3 HSV(vec3 color) { vec3 hsv = rgb2hsv(color); hsv.y = pow(hsv.y, 1.0/satScale); color = hsv2rgb(hsv); return color; } void main() { vec3 bloom = texture(textureUnitPS0, passParameterSem0.xy).xyz; vec3 color = texture(textureUnitPS1, passParameterSem0.xy).xyz; #if (adjust_bloom == 1) bloom *= bloomFactor; #endif color += bloom; #if (tone_mapping == -1) color = clamp(color,0.0,1.0); #elif (tone_mapping == 0) color = BotWToneMap(color); #elif (tone_mapping == 1) color = ACESFilm(color); #endif #if (post_process == 0) color = BotWVibrance(color); #elif (post_process == 1) color = ReshadeVibrance(color); #elif (post_process == 2) color = Contrasty(color); #elif (post_process == 3) color = HSV(color); #endif // export passPixelColor0 = vec4(color, passParameterSem0.w); }