2017-10-18 09:03:31 +02:00
#version 420
#extension GL_ARB_texture_gather : enable
2017-11-07 12:52:21 +01:00
// Adjustable Bloom + Tone Mapping + Adjustable Vibrance(Contrasty)
2017-10-18 09:03:31 +02:00
2017-11-07 12:52:21 +01:00
/*=============================Settings=====================================*/
2017-10-19 04:26:55 +02:00
2017-11-07 12:52:21 +01:00
#define adjust_bloom 1 // 0: disable, 1: enable.
2017-11-08 14:33:33 +01:00
const float bloomFactor = 0.7; // 1.0 is neutral [0,1+]
2017-11-03 21:21:20 +01:00
2017-11-08 14:33:33 +01:00
#define tone_mapping 1
// -1: disable, loss of bright detail/color but keep [0,1] intact
2017-11-07 12:52:21 +01:00
// 0: (Wii U) BotW original
// 1: ACES Filmic
2017-11-08 14:33:33 +01:00
//---------------"ACES Filmic","disable" Parameters-------------//
2017-11-08 08:09:43 +01:00
const float Exposure = 0.6; // [0.0, 1.0+] Adjust exposure
2017-11-07 12:52:21 +01:00
//---------------------------------------------------------------//
2017-11-04 06:55:31 +01:00
2017-11-08 14:33:33 +01:00
#define post_process 0
2017-11-07 12:52:21 +01:00
// -1: disable
// 0: (Wii U) BotW original, only vibrance
2017-11-08 14:33:33 +01:00
// 1: Contrasty
2017-11-07 12:52:21 +01:00
//----------------"BotW original" vibrance adjust-------------//
2017-11-08 14:33:33 +01:00
const float satFactor = 0.25; // 0.18 is neutral. Experimental, adjust native saturation
2017-11-07 12:52:21 +01:00
//---------------------------------------------------------------//
//---------------------"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
2017-11-08 14:33:33 +01:00
const float vibrance = 0.40; // >0: saturate <0: desaturate
const vec3 vibrance_RGB_balance = 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.
const float crushContrast = 0.000; // 0.0 is neutral. Use small increments, loss of shadow detail
2017-11-07 12:52:21 +01:00
//---------------------------------------------------------------//
/*==========================================================================*/
2017-10-18 09:03:31 +02:00
2017-10-19 04:26:55 +02:00
2017-11-07 12:52:21 +01:00
// shader bd8bba59e2149449 // bloom(add), tonemap, saturate
2017-10-18 09:03:31 +02:00
uniform ivec4 uf_remappedPS[1];
2017-11-07 12:52:21 +01:00
layout(binding = 0) uniform sampler2D textureUnitPS0; //bloom
layout(binding = 1) uniform sampler2D textureUnitPS1; //texture, hdr
2017-10-18 09:03:31 +02:00
layout(location = 0) in vec4 passParameterSem0;
layout(location = 0) out vec4 passPixelColor0;
uniform vec2 uf_fragCoordScale;
2017-11-07 12:52:21 +01:00
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) {
2017-11-08 08:09:43 +01:00
color *= Exposure;
2017-11-08 14:33:33 +01:00
float Lumn = getL709(color);
vec4 tm = vec4(color,Lumn);
tm = (tm*(2.51*tm+0.03))/(tm*(2.43*tm+0.59)+0.14); // tonemap
vec3 cpre = tm.w / Lumn * color;
vec3 colorldr = mix(cpre,tm.rgb,vec3(pow(tm.w,2.0)));//refine
return colorldr;
2017-11-07 12:52:21 +01:00
}
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);
2017-11-07 13:42:49 +01:00
float weight = 1.0 + w * satFactor;
2017-11-07 12:52:21 +01:00
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
2017-11-08 14:33:33 +01:00
vec3 coeffVibrance = vibrance_RGB_balance * vibrance;
2017-11-07 12:52:21 +01:00
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));
2017-11-08 14:33:33 +01:00
fColour = ReshadeVibrance(fColour); // reshade's identical, only a little stronger when at same setting
2017-11-07 12:52:21 +01:00
return fColour;
}
2017-11-08 14:33:33 +01:00
// bad curve, see reshade curves.fx
//vec3 Contrasty2(vec3 color) {
// color = clamp(color,0.0,1.0);
// vec3 dark = pow(color,vec3(1.0/dark_thr));
// vec3 bright = pow(color,vec3(1.0/bright_thr));
// float lumn = getL709(color);
// color = mix(dark,bright,lumn);
// color = ReshadeVibrance(color);
// return color;
//}
2017-11-07 12:52:21 +01:00
2017-10-18 09:03:31 +02:00
void main()
{
2017-11-07 12:52:21 +01:00
vec3 bloom = texture(textureUnitPS0, passParameterSem0.xy).xyz;
vec3 color = texture(textureUnitPS1, passParameterSem0.xy).xyz;
2017-11-03 21:21:20 +01:00
#if (adjust_bloom == 1)
2017-11-07 12:52:21 +01:00
bloom *= bloomFactor;
2017-11-03 21:21:20 +01:00
#endif
2017-11-07 12:52:21 +01:00
color += bloom;
#if (tone_mapping == -1)
2017-11-08 14:33:33 +01:00
color = clamp(color*Exposure,0.0,1.0);
2017-11-07 12:52:21 +01:00
#elif (tone_mapping == 0)
color = BotWToneMap(color);
#elif (tone_mapping == 1)
color = ACESFilm(color);
2017-11-04 06:55:31 +01:00
#endif
2017-11-07 12:52:21 +01:00
#if (post_process == 0)
color = BotWVibrance(color);
#elif (post_process == 1)
color = Contrasty(color);
2017-10-22 19:16:40 +02:00
#endif
2017-10-18 09:03:31 +02:00
// export
2017-11-07 12:52:21 +01:00
passPixelColor0 = vec4(color, passParameterSem0.w);
2017-10-18 09:03:31 +02:00
}