[HLSL CODE] Color Grading Filter

share shaders here
Post Reply
  • Author
  • Message
Offline
*sensei*
Posts: 372
Joined: 28 Jul 2013, 23:26

[HLSL CODE] Color Grading Filter

Hello all.

Worked up an entire new code to do color grading effects (much like palette does but then in code and configurable in game).

This will let you set colors for Mid tones, Shadows come from the direct complementary color but can be changed by Hue, it will fade out to white. All controls you possibly want are in GUI but I am open for ideas.

To get an idea about how colors for Shadows, Midtones are distributed you can download this Excel file:
https://drive.google.com/file/d/0B1jPJD ... sp=sharing

You have an option in GUI to view the 'palette' on your screen.

(example with lovely banding artifacts of jpg+flickr)
Image

Here's the code, which should be placed AFTER any form of tonemapping.

GUI ELEMENTS

Code: Select all

bool   Section_Sepia <
	string UIName =  "------Color Tinting---------";
> = {false};
bool use_tinting <
	string UIName = "Enable Tinting";
> = {false};
bool display_gradient <
	string UIName = "Show Color Gradient";
> = {false};
float3 RGB_TintD <
	string UIName="Tint Color Day";
	string UIWidget="Color";
> = {0.725, 0.431, 0.118};
float HighlightPowerD <
	string UIName="Highlight Color Power Day";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float TintPowerD <
	string UIName="Tint Color Power Day";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float ShadowPowerD <
	string UIName="Shadow Color Power Day";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float ShadowStrD <
	string UIName="Add Shadow Color Day";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float SHueAdjustD <
	string UIName="Shift Shadow Hue Day";
	string UIWidget="Spinner";
	float UIMin=-1.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatShadowsD <
	string UIName="Desaturate Shadows Day";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatMidsD <
	string UIName="Desaturate Midtones Day";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatOrigD <
	string UIName="Desaturate Original Day";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float3 RGB_TintN <
	string UIName="Tint Color Night";
	string UIWidget="Color";
> = {0.725, 0.431, 0.118};
float HighlightPowerN <
	string UIName="Highlight Color Power Night";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float TintPowerN <
	string UIName="Tint Color Power Night";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float ShadowPowerN <
	string UIName="Shadow Color Power Night";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float ShadowStrN <
	string UIName="Add Shadow Color Night";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float SHueAdjustN <
	string UIName="Shift Shadow Hue Night";
	string UIWidget="Spinner";
	float UIMin=-1.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatShadowsN <
	string UIName="Desaturate Shadows Night";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatMidsN <
	string UIName="Desaturate Midtones Night";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatOrigN <
	string UIName="Desaturate Original Night";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float3 RGB_TintI <
	string UIName="Tint Color Interior";
	string UIWidget="Color";
> = {0.725, 0.431, 0.118};
float HighlightPowerI <
	string UIName="Highlight Color Power Interior";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float TintPowerI <
	string UIName="Tint Color Power Interior";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float ShadowPowerI <
	string UIName="Shadow Color Power Interior";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=100.0;
	float UIStep=0.001;
> = {1};
float ShadowStrI <
	string UIName="Add Shadow Color Interior";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float SHueAdjustI <
	string UIName="Shift Shadow Hue Interior";
	string UIWidget="Spinner";
	float UIMin=-1.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatShadowsI <
	string UIName="Desaturate Shadows Interior";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatMidsI <
	string UIName="Desaturate Midtones Interior";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float DesatOrigI <
	string UIName="Desaturate Original Interior";
	string UIWidget="Spinner";
	float UIMin=0.0;
	float UIMax=1.0;
	float UIStep=0.001;
> = {0.0};
float3 TonedD <
	string UIName="Effect Strength Day";
	string UIWidget="Color";
> = {0.314, 0.314, 0.314};
float3 TonedN <
	string UIName="Effect Strength Night";
	string UIWidget="Color";
> = {0.314, 0.314, 0.314};
float3 TonedI <
	string UIName="Effect Strength Interior";
	string UIWidget="Color";
> = {0.314, 0.314, 0.314};
HELPER FUNCTIONS (HSL COLOR SPACE CONVERSION)

Code: Select all

float3 HUEToRGB(in float H)
{
	float R = abs(H * 6 - 3) - 1;
	float G = 2 - abs(H * 6 - 2);
	float B = 2 - abs(H * 6 - 4);
	return saturate(float3(R,G,B));
}

float Epsilon = 1e-10;

float3 RGBToHCV(in float3 RGB)
{
	// Based on work by Sam Hocevar and Emil Persson
	float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0/3.0) : float4(RGB.gb, 0.0, -1.0/3.0);
	float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
	float C = Q.x - min(Q.w, Q.y);
	float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
	return float3(H, C, Q.x);
}

float3 RGBToHSL(in float3 RGB)
{
	float3 HCV = RGBToHCV(RGB);
	float L = HCV.z - HCV.y * 0.5;
	float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
	return float3(HCV.x, S, L);
}

float3 HSLToRGB(in float3 HSL)
{
	float3 RGB = HUEToRGB(HSL.x);
	float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
	return (RGB - 0.5) * C + HSL.z;
}

float grayValue(float3 gv)
{
	return dot( gv, float3(0.2125, 0.7154, 0.0721) );
}
PIXEL SHADER PART

Code: Select all

////////////////////////////////////
//          Color Tinting         //
////////////////////////////////////
//By prod80 [ http://www.nexusmods.com/skyrim/users/6440158/ ]
if (use_tinting==true)
{
	float3	RGB_Tint		= lerp( lerp( RGB_TintN, RGB_TintD,	ENightDayFactor ), RGB_TintI, EInteriorFactor );
	float 	DesatMids		= lerp( lerp( DesatMidsN, DesatMidsD, ENightDayFactor ), DesatMidsI, EInteriorFactor );
	float	DesatShadows	= lerp( lerp( DesatShadowsN, DesatShadowsD, ENightDayFactor ), DesatShadowsI, EInteriorFactor );
	float	DesatOrig		= lerp( lerp( DesatOrigN, DesatOrigD, ENightDayFactor ), DesatOrigI, EInteriorFactor );
	float3 	Toned 			= lerp( lerp( TonedN, TonedD, ENightDayFactor ), TonedI, EInteriorFactor );
	float 	ShadowStr		= lerp( lerp( ShadowStrN, ShadowStrD, ENightDayFactor ), ShadowStrI, EInteriorFactor );
	float	TintPower		= lerp( lerp( TintPowerN,	TintPowerD, ENightDayFactor ), TintPowerI, EInteriorFactor );
	float	ShadowPower		= lerp( lerp( ShadowPowerN, ShadowPowerD, ENightDayFactor ), ShadowPowerI, EInteriorFactor );
	float	HighlightPower	= lerp( lerp( HighlightPowerN, HighlightPowerD, ENightDayFactor ), HighlightPowerI, EInteriorFactor );
	float	SHueAdjust		= lerp( lerp( SHueAdjustN, SHueAdjustD, ENightDayFactor ), SHueAdjustI, EInteriorFactor );
	
	color.rgb				= saturate( color.rgb );
	
	if (display_gradient == true )
		color.rgb			= float3( _v0.x, _v0.x, _v0.x );
	
	float gray				= dot( color.rgb, 0.33333333 );
	float shadows			= pow( 1 - gray, TintPower + ShadowPower );
	float highlights		= pow( gray, TintPower + HighlightPower );
	float midtones			= saturate( 1 - shadows - highlights );
	
	float3 RGB_Shadows		= RGBToHSL( RGB_Tint.rgb );
	RGB_Shadows.r			+= 0.5 + SHueAdjust;
		if ( RGB_Shadows.r > 1.0 ) RGB_Shadows.r -= 1.0;
		if ( RGB_Shadows.r < 0.0 ) RGB_Shadows.r += 1.0;
	
	RGB_Shadows.rgb			= saturate( RGB_Shadows.rgb );
	float3 temp_shadows		= RGB_Shadows.rgb;
	RGB_Shadows.rgb			= HSLToRGB( RGB_Shadows.rgb );
	
	//Create gradient
	float3 cg				= saturate( midtones * RGB_Tint.rgb + shadows * RGB_Shadows.rgb + highlights );

	//Mix back with gray 0.33333333, other 'luma' values are INACCURATE in this effect at this stage!
	cg.rgb 					= RGBToHSL( cg.rgb );
	cg.rgb	 				= HSLToRGB( float3( cg.rg, gray ));

	//Shadow color, saturation and final mixing
	temp_shadows.b			= max( temp_shadows.b - ( temp_shadows.b - ShadowStr ), 0.0 );
	temp_shadows.rgb		= HSLToRGB( temp_shadows.rgb );
	cg.rgb 					= max( temp_shadows.rgb, cg.rgb );
	cg.rgb					= lerp( cg.rgb, lerp( cg.rgb, grayValue( cg.rgb ), shadows ), DesatShadows );
	cg.rgb 					= lerp( cg.rgb, lerp( cg.rgb, grayValue( cg.rgb ), midtones ), DesatMids );
	color.rgb 				= lerp( color.rgb, grayValue( color.rgb ), DesatOrig );
	color.rgb 				= lerp( color.rgb, cg.rgb, Toned.rgb );
}

Offline
User avatar
*blah-blah-blah maniac*
Posts: 3136
Joined: 27 Jan 2012, 13:42

Re: [HLSL CODE] Color Grading Filter

Thanks for sharing, I'll give it a go at some point - there can be never enough good color grading solutions.

Offline
*sensei*
Posts: 372
Joined: 28 Jul 2013, 23:26

Re: [HLSL CODE] Color Grading Filter

Totally agreed :)
Post Reply