diff --git a/combine.cc b/combine.cc
index 3d4dd59..e69e7ef 100644
--- a/combine.cc
+++ b/combine.cc
@@ -20,7 +20,10 @@ T_CombinePass::T_CombinePass(
 		bloomAttenuation_( 0.3 ) ,
 		vignette_{
 			1 , 8 , .5 , 1 , 0 , 1
-		}
+		} ,
+		cgLift_{ 0 , 0 , 0 } ,
+		cgGain_{ 1 , 1 , 1 } ,
+		cgGamma_{ 0 , 0 , 0 }
 {
 	program_ = Globals::Shaders( ).pipeline({
 			"fullscreen.v.glsl" , "combine.f.glsl" });
@@ -40,6 +43,9 @@ void T_CombinePass::render( )
 			U_BLOOM_PARAMETERS ,
 			U_VIGNETTE_PARAMETERS_1 ,
 			U_VIGNETTE_PARAMETERS_2 ,
+			U_CG_LIFT ,
+			U_CG_GAIN ,
+			U_CG_GAMMA ,
 		};
 		auto& tm( Globals::Textures( ) );
 		tm.bind( 0 , txImage_ );
@@ -57,6 +63,9 @@ void T_CombinePass::render( )
 				    vignette_ );
 		glProgramUniform2fv( id , U_VIGNETTE_PARAMETERS_2 , 1 ,
 				    vignette_ + 4 );
+		glProgramUniform3fv( id , U_CG_LIFT , 1 , cgLift_ );
+		glProgramUniform3fv( id , U_CG_GAIN , 1 , cgGain_ );
+		glProgramUniform3fv( id , U_CG_GAMMA , 1 , cgGamma_ );
 
 		glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 );
 	}
@@ -65,20 +74,37 @@ void T_CombinePass::render( )
 
 void T_CombinePass::makeUI( )
 {
-	if ( !ImGui::CollapsingHeader( "Combine" ) ) {
+	using namespace ImGui;
+	if ( !CollapsingHeader( "Combine" ) ) {
 		return;
 	}
 
-	ImGui::Text( "Bloom" );
-	ImGui::DragFloat( "Strength" , &bloomStrength_ , .001f , 0. , 10 );
-	ImGui::DragFloat( "Attenuation" , &bloomAttenuation_ , .001f , 0. , 1 );
+	if ( TreeNode( "combine-bloom" , "Bloom" ) ) {
+		DragFloat( "Strength" , &bloomStrength_ , .001f , 0. , 10 );
+		DragFloat( "Attenuation" , &bloomAttenuation_ , .001f , 0. , 1 );
+		TreePop( );
+	}
 
-	ImGui::Text( "Vignette" );
-	ImGui::DragFloat( "Shape mult." , &vignette_[ 0 ] , .01f , 0.5 , 20 );
-	ImGui::DragFloat( "Shape power" , &vignette_[ 1 ] , .01f , .5 , 50 );
-	ImGui::DragFloat( "Aspect ratio" , &vignette_[ 2 ] , .001f , 0 , 1 );
-	ImGui::DragFloat( "Shape reverse" , &vignette_[ 3 ] , .001f , .2 , 5 );
-	ImGui::DragFloat( "Apply base" , &vignette_[ 4 ] , .001f , 0 , 1 );
-	ImGui::DragFloat( "Apply max" , &vignette_[ 5 ] , .001f , 0 , 1 );
+	if ( TreeNode( "Vignette" ) ) {
+		DragFloat( "Shape mult." , &vignette_[ 0 ] , .01f , 0.5 , 20 );
+		DragFloat( "Shape power" , &vignette_[ 1 ] , .01f , .5 , 50 );
+		DragFloat( "Aspect ratio" , &vignette_[ 2 ] , .001f , 0 , 1 );
+		DragFloat( "Shape reverse" , &vignette_[ 3 ] , .001f , .2 , 5 );
+		DragFloat( "Apply base" , &vignette_[ 4 ] , .001f , 0 , 1 );
+		DragFloat( "Apply max" , &vignette_[ 5 ] , .001f , 0 , 1 );
+		TreePop( );
+	}
+
+	if ( TreeNode( "Color grading" ) ) {
+		DragFloat( "Lift / R" , &cgLift_[ 0 ] , .0001f , -1 , 1 );
+		DragFloat( "Lift / G" , &cgLift_[ 1 ] , .0001f , -1 , 1 );
+		DragFloat( "Lift / B" , &cgLift_[ 2 ] , .0001f , -1 , 1 );
+		DragFloat( "Gain / R" , &cgGain_[ 0 ] , .001f , 0 , 2 );
+		DragFloat( "Gain / G" , &cgGain_[ 1 ] , .001f , 0 , 2 );
+		DragFloat( "Gain / B" , &cgGain_[ 2 ] , .001f , 0 , 2 );
+		DragFloat( "Gamma / R" , &cgGamma_[ 0 ] , .001f , -2 , 10 );
+		DragFloat( "Gamma / G" , &cgGamma_[ 1 ] , .001f , -2 , 10 );
+		DragFloat( "Gamma / B" , &cgGamma_[ 2 ] , .001f , -2 , 10 );
+		TreePop( );
+	}
 }
-
diff --git a/combine.hh b/combine.hh
index a5aca5f..0b5dfff 100644
--- a/combine.hh
+++ b/combine.hh
@@ -26,5 +26,9 @@ struct T_CombinePass
 	float bloomAttenuation_;
 
 	float vignette_[ 6 ];
+
+	float cgLift_[ 3 ];
+	float cgGain_[ 3 ];
+	float cgGamma_[ 3 ];
 };
 
diff --git a/shaders/combine.f.glsl b/shaders/combine.f.glsl
index f41c99d..a6b4423 100644
--- a/shaders/combine.f.glsl
+++ b/shaders/combine.f.glsl
@@ -6,16 +6,11 @@ layout( location = 0 ) uniform sampler2D u_MainInput;
 layout( location = 1 ) uniform sampler2D u_BlurInput;
 layout( location = 2 ) uniform vec2 u_OutputSize;
 layout( location = 3 ) uniform vec2 u_Bloom;
-
-// Vignette parameters
-// 1.x = shape multiplier
-// 1.y = shape power
-// 1.z = aspect ratio
-// 1.w = reverse power multiplier
-// 2.x = apply base
-// 2.y = apply max
 layout( location = 4 ) uniform vec4 u_Vignette1;
 layout( location = 5 ) uniform vec2 u_Vignette2;
+layout( location = 6 ) uniform vec3 u_ColorLift;
+layout( location = 7 ) uniform vec3 u_ColorGain;
+layout( location = 8 ) uniform vec3 u_ColorGamma;
 
 #define uVigShapeMul (u_Vignette1.x)
 #define uVigShapePow (u_Vignette1.y)
@@ -41,11 +36,8 @@ void main( void )
 	}
 	o_Color = o_Color + bloom / 2.2;
 
-	// Color grading test
-	vec3 uColorGain = vec3( .95 , 1.1 , 1.4 ) ,
-	     uColorLift = vec3( 0 , 0 , .003 ) ,
-	     uColorGamma = vec3( -.2 , 0.1 , .1 );
-	o_Color = ( o_Color * ( uColorGain - uColorLift ) ) + uColorLift;
+	// Color grading
+	o_Color = ( o_Color * ( u_ColorGain - u_ColorLift ) ) + u_ColorLift;
 
 	// Vignette
 	vec2 vShape = pow( abs( pos * 2 - 1 ) * uVigShapeMul ,
@@ -60,5 +52,5 @@ void main( void )
 	o_Color = o_Color / ( o_Color + 1. );
 
 	// Gamma
-	o_Color = pow( o_Color , vec3( 1 ) / ( uColorGamma + 2.2 ) );
+	o_Color = pow( o_Color , vec3( 1 ) / ( u_ColorGamma + 2.2 ) );
 }