Bloom highpass filter
This commit is contained in:
parent
f1628c0cd5
commit
4249691406
4 changed files with 64 additions and 21 deletions
|
@ -9,11 +9,11 @@ layout( location = 0 ) out vec3 color;
|
||||||
void main( void )
|
void main( void )
|
||||||
{
|
{
|
||||||
vec2 tmp = gl_FragCoord.xy / u_OutputSize;
|
vec2 tmp = gl_FragCoord.xy / u_OutputSize;
|
||||||
float f = .8;
|
float f = .7;
|
||||||
color = textureLod( u_MainInput , tmp , 0 ).rgb;
|
color = textureLod( u_MainInput , tmp , 0 ).rgb;
|
||||||
for ( int i = 0 ; i < 5 ; i ++ ) {
|
for ( int i = 0 ; i < 5 ; i ++ ) {
|
||||||
color += f * textureLod( u_BlurInput , tmp , i ).rgb;
|
color += f * textureLod( u_BlurInput , tmp , i ).rgb;
|
||||||
f *= .90;
|
f *= .7;
|
||||||
}
|
}
|
||||||
color = color / ( color + 1. );
|
color = color / ( color + 1. );
|
||||||
color = pow( color , vec3( 2.2 ) );
|
color = pow( color , vec3( 2.2 ) );
|
||||||
|
|
15
bloom-highpass.glsl
Normal file
15
bloom-highpass.glsl
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout( location = 0 ) uniform sampler2D u_Input;
|
||||||
|
layout( location = 1 ) uniform int u_LOD;
|
||||||
|
layout( location = 2 ) uniform vec2 u_InputSize;
|
||||||
|
layout( location = 3 ) uniform vec3 u_FilterParams;
|
||||||
|
|
||||||
|
layout( location = 0 ) out vec3 color;
|
||||||
|
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
vec3 c = textureLod( u_Input , gl_FragCoord.xy / u_InputSize.xy , u_LOD ).xyz;
|
||||||
|
color = max( vec3(0) , ( pow( c , vec3(u_FilterParams.x) ) * u_FilterParams.y - c ) / u_FilterParams.z );
|
||||||
|
}
|
|
@ -5,22 +5,28 @@ layout( location = 1 ) uniform vec2 u_OutputSize;
|
||||||
layout( location = 2 ) uniform vec2 u_InputSize;
|
layout( location = 2 ) uniform vec2 u_InputSize;
|
||||||
layout( location = 3 ) uniform int u_SourceLOD;
|
layout( location = 3 ) uniform int u_SourceLOD;
|
||||||
layout( location = 4 ) uniform vec2 u_Direction;
|
layout( location = 4 ) uniform vec2 u_Direction;
|
||||||
layout( location = 5 ) uniform vec3 u_Weights;
|
layout( location = 5 ) uniform vec4 u_Weights;
|
||||||
|
|
||||||
layout( location = 0 ) out vec3 color;
|
layout( location = 0 ) out vec3 color;
|
||||||
|
|
||||||
void main( void )
|
void main( void )
|
||||||
{
|
{
|
||||||
vec2 tmp = gl_FragCoord.xy / u_OutputSize;
|
vec2 tmp = gl_FragCoord.xy / u_OutputSize;
|
||||||
vec2 displace1 = vec2( 2.5 ) * u_Direction / u_InputSize;
|
const float disp = 4;
|
||||||
vec2 displace2 = vec2( 5. ) * u_Direction / u_InputSize;
|
vec2 displace1 = vec2( disp * 1 ) * u_Direction / u_OutputSize;
|
||||||
float wt = u_Weights.x + u_Weights.y * 2 + u_Weights.z * 2;
|
vec2 displace2 = vec2( disp * 2 ) * u_Direction / u_OutputSize;
|
||||||
|
vec2 displace3 = vec2( disp * 3 ) * u_Direction / u_OutputSize;
|
||||||
|
float wt = u_Weights.x + u_Weights.y * 2 + u_Weights.z * 2 + u_Weights.w * 2;
|
||||||
color = u_Weights.x * textureLod( u_InputTexture , tmp , u_SourceLOD ).xyz
|
color = u_Weights.x * textureLod( u_InputTexture , tmp , u_SourceLOD ).xyz
|
||||||
+ u_Weights.y * (
|
+ u_Weights.y * (
|
||||||
textureLod( u_InputTexture , tmp + displace1 , u_SourceLOD ).xyz
|
textureLod( u_InputTexture , tmp + displace1 , u_SourceLOD ).xyz
|
||||||
+ textureLod( u_InputTexture , tmp - displace1 , u_SourceLOD ).xyz )
|
+ textureLod( u_InputTexture , tmp - displace1 , u_SourceLOD ).xyz )
|
||||||
+ u_Weights.z * (
|
+ u_Weights.z * (
|
||||||
textureLod( u_InputTexture , tmp + displace2 , u_SourceLOD ).xyz
|
textureLod( u_InputTexture , tmp + displace2 , u_SourceLOD ).xyz
|
||||||
+ textureLod( u_InputTexture , tmp - displace2 , u_SourceLOD ).xyz );
|
+ textureLod( u_InputTexture , tmp - displace2 , u_SourceLOD ).xyz )
|
||||||
|
+ u_Weights.w * (
|
||||||
|
textureLod( u_InputTexture , tmp + displace3 , u_SourceLOD ).xyz
|
||||||
|
+ textureLod( u_InputTexture , tmp - displace3 , u_SourceLOD ).xyz )
|
||||||
|
;
|
||||||
color /= wt;
|
color /= wt;
|
||||||
}
|
}
|
||||||
|
|
50
main.cc
50
main.cc
|
@ -30,12 +30,16 @@ struct T_Main
|
||||||
T_FilesWatcher watcher;
|
T_FilesWatcher watcher;
|
||||||
std::unique_ptr< T_ShaderProgram > spRaymarch;
|
std::unique_ptr< T_ShaderProgram > spRaymarch;
|
||||||
std::unique_ptr< T_ShaderProgram > spCopy;
|
std::unique_ptr< T_ShaderProgram > spCopy;
|
||||||
|
std::unique_ptr< T_ShaderProgram > spBloomFilter;
|
||||||
std::unique_ptr< T_ShaderProgram > spBlur;
|
std::unique_ptr< T_ShaderProgram > spBlur;
|
||||||
std::unique_ptr< T_ShaderProgram > spBloomCombine;
|
std::unique_ptr< T_ShaderProgram > spBloomCombine;
|
||||||
|
|
||||||
std::unique_ptr< T_Texture > txRaymarchOutput;
|
std::unique_ptr< T_Texture > txRaymarchOutput;
|
||||||
std::unique_ptr< T_Rendertarget > rtRaymarchOutput;
|
std::unique_ptr< T_Rendertarget > rtRaymarchOutput;
|
||||||
|
|
||||||
|
std::unique_ptr< T_Texture > txBloomInput;
|
||||||
|
std::unique_ptr< T_Rendertarget > rtBloomInput;
|
||||||
|
|
||||||
std::unique_ptr< T_Texture > txBlur0 , txBlur1;
|
std::unique_ptr< T_Texture > txBlur0 , txBlur1;
|
||||||
std::vector< std::unique_ptr< T_Rendertarget > > rtBlur0 , rtBlur1;
|
std::vector< std::unique_ptr< T_Rendertarget > > rtBlur0 , rtBlur1;
|
||||||
|
|
||||||
|
@ -76,6 +80,12 @@ T_Main::T_Main( )
|
||||||
rtRaymarchOutput = std::make_unique < T_Rendertarget >(
|
rtRaymarchOutput = std::make_unique < T_Rendertarget >(
|
||||||
T_RendertargetSetup( ).add( *txRaymarchOutput ).create( ) );
|
T_RendertargetSetup( ).add( *txRaymarchOutput ).create( ) );
|
||||||
|
|
||||||
|
txBloomInput = std::make_unique< T_Texture >(
|
||||||
|
1280 , 720 , E_TexType::RGB16F );
|
||||||
|
txBloomInput->wrap( E_TexWrap::CLAMP_BORDER ).samplingMode( E_TexSampling::LINEAR );
|
||||||
|
rtBloomInput = std::make_unique < T_Rendertarget >(
|
||||||
|
T_RendertargetSetup( ).add( *txBloomInput ).create( ) );
|
||||||
|
|
||||||
txBlur0 = std::make_unique< T_Texture >( 1280 , 720 , E_TexType::RGB16F , 5 );
|
txBlur0 = std::make_unique< T_Texture >( 1280 , 720 , E_TexType::RGB16F , 5 );
|
||||||
txBlur0->wrap( E_TexWrap::CLAMP_EDGE ).samplingMode( E_TexSampling::LINEAR );
|
txBlur0->wrap( E_TexWrap::CLAMP_EDGE ).samplingMode( E_TexSampling::LINEAR );
|
||||||
txBlur1 = std::make_unique< T_Texture >( 1280 , 720 , E_TexType::RGB16F , 5 );
|
txBlur1 = std::make_unique< T_Texture >( 1280 , 720 , E_TexType::RGB16F , 5 );
|
||||||
|
@ -212,6 +222,25 @@ void T_Main::render( )
|
||||||
glRectf( -1, -1 , 1 , 1 );
|
glRectf( -1, -1 , 1 , 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( spBloomFilter->activate( ) ) {
|
||||||
|
enum {
|
||||||
|
U_TEXTURE = 0 ,
|
||||||
|
U_LOD = 1 ,
|
||||||
|
U_INPUT_SIZE = 2 ,
|
||||||
|
U_PARAMS = 3 ,
|
||||||
|
};
|
||||||
|
rtBloomInput->activate( );
|
||||||
|
T_TextureBinding tb( 0 );
|
||||||
|
tb.set( U_TEXTURE , *txRaymarchOutput );
|
||||||
|
tb.bind( );
|
||||||
|
glUniform1i( U_LOD , 0 );
|
||||||
|
glUniform2f( U_INPUT_SIZE ,
|
||||||
|
txRaymarchOutput->width( ) ,
|
||||||
|
txRaymarchOutput->height( ) );
|
||||||
|
glUniform3f( U_PARAMS , 1.6 , 1.2 , .95 );
|
||||||
|
glRectf( -1, -1 , 1 , 1 );
|
||||||
|
}
|
||||||
|
|
||||||
if ( spBlur->activate( ) ) {
|
if ( spBlur->activate( ) ) {
|
||||||
enum {
|
enum {
|
||||||
U_TEXTURE = 0 ,
|
U_TEXTURE = 0 ,
|
||||||
|
@ -221,7 +250,7 @@ void T_Main::render( )
|
||||||
U_DIRECTION = 4 ,
|
U_DIRECTION = 4 ,
|
||||||
U_WEIGHTS = 5 ,
|
U_WEIGHTS = 5 ,
|
||||||
};
|
};
|
||||||
glUniform3f( U_WEIGHTS , 0.5 , 0.25 , 0.125 );
|
glUniform4f( U_WEIGHTS , 0.324 , 0.232 , 0.0855 , 0.0205 );
|
||||||
for ( int i = 0 ; i < 5 ; i ++ ) {
|
for ( int i = 0 ; i < 5 ; i ++ ) {
|
||||||
// IB RMO B0 B1 B0 B1 B0
|
// IB RMO B0 B1 B0 B1 B0
|
||||||
// OB B0/0 B1/0 B0/1 B1/1 B0/2 B1/2
|
// OB B0/0 B1/0 B0/1 B1/1 B0/2 B1/2
|
||||||
|
@ -231,7 +260,7 @@ void T_Main::render( )
|
||||||
T_TextureBinding tb( 0 );
|
T_TextureBinding tb( 0 );
|
||||||
uint32_t w , h;
|
uint32_t w , h;
|
||||||
if ( i == 0 ) {
|
if ( i == 0 ) {
|
||||||
tb.set( U_TEXTURE , *txRaymarchOutput );
|
tb.set( U_TEXTURE , *txBloomInput );
|
||||||
w = txRaymarchOutput->width( );
|
w = txRaymarchOutput->width( );
|
||||||
h = txRaymarchOutput->height( );
|
h = txRaymarchOutput->height( );
|
||||||
} else {
|
} else {
|
||||||
|
@ -244,7 +273,7 @@ void T_Main::render( )
|
||||||
rtBlur0[ i ]->activate( );
|
rtBlur0[ i ]->activate( );
|
||||||
#ifdef INTRUSIVE_TRACES
|
#ifdef INTRUSIVE_TRACES
|
||||||
printf( "BLUR %d/H IT %p SLOD %d IS %dx%d OS %dx%d\n" ,
|
printf( "BLUR %d/H IT %p SLOD %d IS %dx%d OS %dx%d\n" ,
|
||||||
i , &(*( i == 0 ? txRaymarchOutput : txBlur1 ) ) ,
|
i , &(*( i == 0 ? txBloomInput : txBlur1 ) ) ,
|
||||||
slod , w , h , rtBlur0[ i ]->width( ) , rtBlur0[ i ]->height( ) );
|
slod , w , h , rtBlur0[ i ]->width( ) , rtBlur0[ i ]->height( ) );
|
||||||
#endif
|
#endif
|
||||||
glUniform2f( U_OUTPUT_SIZE , rtBlur0[ i ]->width( ) , rtBlur0[ i ]->height( ) );
|
glUniform2f( U_OUTPUT_SIZE , rtBlur0[ i ]->width( ) , rtBlur0[ i ]->height( ) );
|
||||||
|
@ -276,16 +305,6 @@ void T_Main::render( )
|
||||||
T_Rendertarget::MainOutput( );
|
T_Rendertarget::MainOutput( );
|
||||||
glClearColor( 1 , 0 , 1 , 1 );
|
glClearColor( 1 , 0 , 1 , 1 );
|
||||||
glClear( GL_COLOR_BUFFER_BIT );
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
#if 0
|
|
||||||
if ( spCopy->activate( ) ) {
|
|
||||||
T_TextureBinding tb( 0 );
|
|
||||||
tb.set( 0 , *txBlur1 );
|
|
||||||
tb.bind( );
|
|
||||||
glUniform1i( 1 , 3 );
|
|
||||||
glRectf( -1, -1 , 1 , 1 );
|
|
||||||
glBindTexture( GL_TEXTURE_2D , 0 );
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( spBloomCombine->activate( ) ) {
|
if ( spBloomCombine->activate( ) ) {
|
||||||
T_TextureBinding main( 0 ) , blur( 1 );
|
T_TextureBinding main( 0 ) , blur( 1 );
|
||||||
main.set( 0 , *txRaymarchOutput );
|
main.set( 0 , *txRaymarchOutput );
|
||||||
|
@ -296,7 +315,6 @@ void T_Main::render( )
|
||||||
glRectf( -1, -1 , 1 , 1 );
|
glRectf( -1, -1 , 1 , 1 );
|
||||||
glBindTexture( GL_TEXTURE_2D , 0 );
|
glBindTexture( GL_TEXTURE_2D , 0 );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
glUseProgram( 0 );
|
glUseProgram( 0 );
|
||||||
ImGui::Render( );
|
ImGui::Render( );
|
||||||
|
@ -317,6 +335,10 @@ void T_Main::initProgram( )
|
||||||
spCopy->addFile( "copy.glsl" );
|
spCopy->addFile( "copy.glsl" );
|
||||||
spCopy->load( );
|
spCopy->load( );
|
||||||
|
|
||||||
|
spBloomFilter = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER , watcher );
|
||||||
|
spBloomFilter->addFile( "bloom-highpass.glsl" );
|
||||||
|
spBloomFilter->load( );
|
||||||
|
|
||||||
spBlur = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER , watcher );
|
spBlur = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER , watcher );
|
||||||
spBlur->addFile( "blur-pass.glsl" );
|
spBlur->addFile( "blur-pass.glsl" );
|
||||||
spBlur->load( );
|
spBlur->load( );
|
||||||
|
|
Loading…
Reference in a new issue