diff --git a/combine.cc b/combine.cc index 93a3747..3d4dd59 100644 --- a/combine.cc +++ b/combine.cc @@ -17,7 +17,10 @@ T_CombinePass::T_CombinePass( __rw__ T_Texture& bloom ) : txImage_( image ) , txBloom_( bloom ) , bloomStrength_( 0.45 ) , - bloomAttenuation_( 0.3 ) + bloomAttenuation_( 0.3 ) , + vignette_{ + 1 , 8 , .5 , 1 , 0 , 1 + } { program_ = Globals::Shaders( ).pipeline({ "fullscreen.v.glsl" , "combine.f.glsl" }); @@ -30,16 +33,30 @@ void T_CombinePass::render( ) glClearColor( 1 , 0 , 1 , 1 ); glClear( GL_COLOR_BUFFER_BIT ); if ( program_.valid( ) ) { + enum { + U_MAIN_INPUT , + U_BLOOM_INPUT , + U_OUTPUT_SIZE , + U_BLOOM_PARAMETERS , + U_VIGNETTE_PARAMETERS_1 , + U_VIGNETTE_PARAMETERS_2 , + }; auto& tm( Globals::Textures( ) ); tm.bind( 0 , txImage_ ); tm.bind( 1 , txBloom_ ); const auto id( program_.program( E_ShaderType::FRAGMENT ) ); program_.enable( ); - glProgramUniform1i( id , 0 , 0 ); - glProgramUniform1i( id , 1 , 1 ); - glProgramUniform2f( id , 2 , txImage_.width( ) , txImage_.height( ) ); - glProgramUniform2f( id , 3 , bloomStrength_ , bloomAttenuation_ ); + glProgramUniform1i( id , U_MAIN_INPUT , 0 ); + glProgramUniform1i( id , U_BLOOM_INPUT , 1 ); + glProgramUniform2f( id , U_OUTPUT_SIZE , + txImage_.width( ) , txImage_.height( ) ); + glProgramUniform2f( id , U_BLOOM_PARAMETERS , + bloomStrength_ , bloomAttenuation_ ); + glProgramUniform4fv( id , U_VIGNETTE_PARAMETERS_1 , 1 , + vignette_ ); + glProgramUniform2fv( id , U_VIGNETTE_PARAMETERS_2 , 1 , + vignette_ + 4 ); glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 ); } @@ -52,7 +69,16 @@ void T_CombinePass::makeUI( ) return; } - ImGui::DragFloat( "Bloom strength" , &bloomStrength_ , .001f , 0. , 10 ); - ImGui::DragFloat( "Bloom attenuation" , &bloomAttenuation_ , .001f , 0. , 1 ); + ImGui::Text( "Bloom" ); + ImGui::DragFloat( "Strength" , &bloomStrength_ , .001f , 0. , 10 ); + ImGui::DragFloat( "Attenuation" , &bloomAttenuation_ , .001f , 0. , 1 ); + + 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 ); } diff --git a/combine.hh b/combine.hh index 396d3e9..a5aca5f 100644 --- a/combine.hh +++ b/combine.hh @@ -24,5 +24,7 @@ struct T_CombinePass float bloomStrength_; float bloomAttenuation_; + + float vignette_[ 6 ]; }; diff --git a/shaders/combine.f.glsl b/shaders/combine.f.glsl index 4b9a99a..58cdcab 100644 --- a/shaders/combine.f.glsl +++ b/shaders/combine.f.glsl @@ -5,22 +5,54 @@ 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_Parameters; +layout( location = 3 ) uniform vec2 u_Bloom; -layout( location = 0 ) out vec3 color; +// 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; + +#define uVigShapeMul (u_Vignette1.x) +#define uVigShapePow (u_Vignette1.y) +#define uVigAspect (u_Vignette1.z) +#define uVigShapeReverse (u_Vignette1.w) +#define uVigApplyBase (u_Vignette2.x) +#define uVigApplyMax (u_Vignette2.y) + + +layout( location = 0 ) out vec3 o_Color; void main( void ) { - vec2 tmp = gl_FragCoord.xy / u_OutputSize; - float f = u_Parameters.x; - color = textureLod( u_MainInput , tmp , 0 ).rgb; + vec2 pos = gl_FragCoord.xy / u_OutputSize; + float f = u_Bloom.x; + o_Color = textureLod( u_MainInput , pos , 0 ).rgb; + + // Bloom vec3 bloom = vec3( 0 ); for ( int i = 0 ; i < 6 ; i ++ ) { - bloom += f * textureLod( u_BlurInput , tmp , i ).rgb; - f = pow( f , u_Parameters.y + 1 ); + bloom += f * textureLod( u_BlurInput , pos , i ).rgb; + f = pow( f , u_Bloom.y + 1 ); } - color = color + bloom / 2.2; + o_Color = o_Color + bloom / 2.2; - color = color / ( color + 1. ); - color = pow( color , vec3( 1.0 / 2.2 ) ); + // Vignette + vec2 vShape = pow( abs( pos * 2 - 1 ) * uVigShapeMul , + vec2( uVigShapePow ) ); + float vignette = 1 - pow( + 2 * ( uVigAspect * vShape.x + ( 1 - uVigAspect) * vShape.y ) , + 1 / ( uVigShapePow * uVigShapeReverse ) ); + o_Color *= uVigApplyBase + smoothstep( + uVigApplyBase , uVigApplyBase + uVigApplyMax , vignette ); + + // Reinhart + o_Color = o_Color / ( o_Color + 1. ); + + // Gamma + o_Color = pow( o_Color , vec3( 1.0 / 2.2 ) ); }