Who can deny it? The current saturation, brightness, and contrast post effects just are lacking. They seem to basically play with the brightness, period. So I searched online, and found an existing S.B.C. function written in GLSL.
I went ahead and replaced the setup in postfilter.frag to utilize this function, and I now get much better results when using the Saturation, Brightness, and Contrast sliders. They just seem to give me the right "feel" of appearance for the values. Brightness of 2.0 looks twice as bright, not twice as gray/washed out, etc.
Below is a drop in replacement for postfilter.frag:
varying vec4 fragcolor;
varying vec4 fragcoord;
//==========================================
//Textures
//==========================================
uniform sampler2D texture0; //color
uniform sampler2D texture1; //depth
uniform sampler2D texture2; //normal
uniform sampler2D texture3; //blurred bloom buffer
uniform sampler2D texture4; //unblurred bloom buffer
uniform sampler2D texture5; //caustics frame 1
uniform sampler2D texture6; //blurred DOF texture
uniform sampler2D texture7; //wobble texture / caustics frame 2
uniform sampler2D texture10; //noise texture for effects
uniform sampler2D texture11; //ssao texture
uniform float contrast = 1.0;
uniform float brightness = 1.0;
uniform float saturation = 1.0;
//==========================================
//Automatic uniforms
//==========================================
uniform float apptime;
uniform vec2 buffersize;
uniform vec2 camerarange;
uniform float camerazoom;
include "depthtozposition.frag"
//==========================================
//HDR uniforms
//==========================================
uniform float hdrexposure;
//==========================================
// Fog variables
//==========================================
uniform vec4 fogcolor = vec4(1.0);
uniform vec2 fogrange = vec2(0.1,1000.0);
//==========================================
// DOF variables
//==========================================
uniform vec2 dofnearrange;
uniform vec2 doffarrange;
uniform float dofstrength=1.0;
//==========================================
// Caustics variables
//==========================================
uniform vec4 causticsmappingaxes[4];
uniform float causticsframeinterpolation;
uniform vec4 causticscolor;
//==========================================
// Volumetric light scattering variables
//==========================================
#ifdef LW_GODRAYS
uniform vec3 screenlightpos;
uniform vec3 lightvector;
uniform vec4 raycolor = vec4(1.0);
//uniform float exposure = 0.35;
#define exposure 1.0
#define RAYSAMPLES 64
#define MAXRAYLENGTH 1.0
#endif
//==========================================
// Motion blur variables
//==========================================
uniform vec2 motionblurvector;
uniform float motionblurstrength = 1.0;
uniform float motionblurdistance;
//==========================================
// SSAO Functions
//==========================================
#ifdef LW_SSAO
float ao=0;
#define aointensitybias -0.55
#define ssaostrength 1.0
float readDepth( in vec2 coord ) {
//#ifndef __GLSL_CG_DATA_TYPES
// coord.y = 1.0 - coord.y;
//#endif
return (2.0 * camerarange.x) / (camerarange.y + camerarange.x - texture2D( texture1, coord ).x * (camerarange.y - camerarange.x)) * camerarange.y;
}
float compareDepths( in float depth1, in float depth2 ) {
float aoCap = 1.0;
float aoMultiplier=10.0;
float depthTolerance=0.000;
float aorange = 100.0;///(camerarange.y-camerarange.x);// units in space the AO effect extends to (this gets divided by the camera far range
float diff = ( clamp(1.0-(depth1-depth2) / aorange,0.0,1.0) );
float ao = min(aoCap,max(0.0,depth1-depth2-depthTolerance)) * diff;
ao *= aoMultiplier;
ao=clamp(ao,0.0,1.0);
return ao;
}
#endif
vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con)
{
// Increase or decrease theese values to adjust r, g and b color channels seperately
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color * brt;
vec3 intensity = vec3(dot(brtColor, LumCoeff));
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}
//==========================================
// Main
//==========================================
void main( void ) {
//==========================================
//General variables
//==========================================
vec2 texcoord = gl_FragCoord.xy/buffersize;
vec4 color;
float depth;
float lineardepth;
vec3 normal;
vec4 cnormal;
vec4 outputcolor;
vec2 pixelsize = 1.0/buffersize;
float irisadjustment=1.0;
float bloomstrength = 1.0;
float bloomirisadjustment=2.0;
#ifdef LW_WOBBLE
Include "wobble.frag"
#endif
color = texture2D( texture0, texcoord ) * fragcolor;
depth = texture2D( texture1, texcoord ).x;
cnormal=texture2D( texture2, texcoord );
normal = cnormal.xyz * 2.0 - 1.0;
lineardepth = DepthToZPosition( depth );
outputcolor = color;
float pixelbrightness = outputcolor.r * 0.3 + outputcolor.g * 0.59 + outputcolor.b * 0.11;
//==========================================
// Now include the effects we want
//==========================================
#ifdef LW_HDR
include "hdr.frag"
#endif
#ifdef LW_CAUSTICS
include "caustics.frag"
#endif
#ifdef LW_MOTIONBLUR
include "MotionBlur.frag"
#endif
#ifdef LW_BRIGHTEN
outputcolor = max( outputcolor, texture2D(texture4,texcoord).w * texture2D(texture5,texcoord) );
#endif
#ifdef LW_NEARDOF
Include "neardof.frag"
#endif
#ifdef LW_FARDOF
Include "fardof.frag"
#endif
#ifdef LW_GODRAYS
Include "godrays.frag"
#endif
#ifdef LW_SSAO
float gray = outputcolor.r * 0.3 + outputcolor.g * 0.59 + outputcolor.b * 0.11;
vec4 ssaocolor = texture2D(texture11,texcoord);
ao = ssaocolor.x;
outputcolor.rgb = mix(outputcolor.rgb*ao,outputcolor.rgb,gray+aointensitybias);
//outputcolor.x = outputcolor.rgb*0.5;
//outputcolor.x += ssaocolor.x * 0.75;
//outputcolor.y += ssaocolor.y * 0.75;
//outputcolor.z += ssaocolor.z * 0.75;
//outputcolor = vec4(ao);
//outputcolor=ssaocolor;
#endif
#ifdef LW_DISTANCEFOG
Include "fog.frag"
#endif
#ifdef LW_BLOOM
Include "bloom.frag"
#endif
#ifdef LW_GAUSSIAN
Include "gaussian.frag"
#endif
//#ifdef LW_BRIGHTNESS
//Include "brightness.frag"
//#endif
//#ifdef LW_CONTRAST
//Include "contrast.frag"
//#endif
//#ifdef LW_SATURATION
//Include "saturation.frag"
//#endif
outputcolor.rgb = ContrastSaturationBrightness(outputcolor.rgb,brightness,saturation,contrast);
//==========================================
// Set the fragment color to the output variable
//==========================================
gl_FragColor = outputcolor;
gl_FragDepth = depth;
}