Render SSAO to offscreen FBO

This commit is contained in:
Robert Beckebans 2016-01-06 22:37:16 +01:00
parent 9f83e84f6f
commit 8a861c7914
10 changed files with 111 additions and 43 deletions

View file

@ -298,10 +298,10 @@ const float MIN_RADIUS = 3.0; // pixels
void main( PS_IN fragment, out PS_OUT result ) void main( PS_IN fragment, out PS_OUT result )
{ {
result.color = float4( 0.0, 0.0, 0.0, 1.0 ); result.color = float4( 1.0, 0.0, 0.0, 1.0 );
#if 1 #if 0
if( fragment.texcoord0.x < 0.15 ) if( fragment.texcoord0.x < 0.25 )
{ {
discard; discard;
} }

View file

@ -199,13 +199,7 @@ float calculateBilateralWeight( float key, float tapKey, ivec2 tapLoc, float3 n_
void main( PS_IN fragment, out PS_OUT result ) void main( PS_IN fragment, out PS_OUT result )
{ {
#if 1
if( fragment.texcoord0.x < 0.5 )
{
discard;
}
#endif
//# if __VERSION__ < 330 //# if __VERSION__ < 330
float gaussian[R + 1]; float gaussian[R + 1];
// if R == 0, we never call this shader // if R == 0, we never call this shader
@ -254,10 +248,23 @@ void main( PS_IN fragment, out PS_OUT result )
VALUE_TYPE sum = temp.VALUE_COMPONENTS; VALUE_TYPE sum = temp.VALUE_COMPONENTS;
#if 0
if( fragment.texcoord0.x < 0.5 )
{
//discard;
//result.color = float4( temp.rgb, 1.0 );
result.color = float4( float3( keyPassThrough ), 1.0 );
return;
}
#endif
if( key == 1.0 ) if( key == 1.0 )
{ {
// Sky pixel (if you aren't using depth keying, disable this test) // Sky pixel (if you aren't using depth keying, disable this test)
aoResult = sum; aoResult = sum;
#if defined(BRIGHTPASS)
result.color = float4( aoResult, aoResult, aoResult, 1.0 );
#endif
return; return;
} }
@ -341,5 +348,7 @@ void main( PS_IN fragment, out PS_OUT result )
const float epsilon = 0.0001; const float epsilon = 0.0001;
aoResult = sum / ( totalWeight + epsilon ); aoResult = sum / ( totalWeight + epsilon );
//result.color = float4( aoResult, aoResult, aoResult, 1.0 ); #if defined(BRIGHTPASS)
result.color = float4( aoResult, aoResult, aoResult, 1.0 );
#endif
} }

View file

@ -144,16 +144,28 @@ void Framebuffer::Init()
// BLOOM // BLOOM
for( int i = 0; i < 2; i++ ) for( int i = 0; i < MAX_BLOOM_BUFFERS; i++ )
{ {
globalFramebuffers.bloomRenderFBO[i] = new Framebuffer( va( "_bloomRender%i", i ), glConfig.nativeScreenWidth, glConfig.nativeScreenHeight ); globalFramebuffers.bloomRenderFBO[i] = new Framebuffer( va( "_bloomRender%i", i ), glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
globalFramebuffers.bloomRenderFBO[i]->Bind(); globalFramebuffers.bloomRenderFBO[i]->Bind();
globalFramebuffers.bloomRenderFBO[i]->AddColorBuffer( GL_RGBA8, 0 ); globalFramebuffers.bloomRenderFBO[i]->AddColorBuffer( GL_RGBA8, 0 );
globalFramebuffers.bloomRenderFBO[i]->AttachImage2D( GL_TEXTURE_2D, globalImages->bloomRender[i], 0 ); globalFramebuffers.bloomRenderFBO[i]->AttachImage2D( GL_TEXTURE_2D, globalImages->bloomRenderImage[i], 0 );
globalFramebuffers.bloomRenderFBO[i]->Check(); globalFramebuffers.bloomRenderFBO[i]->Check();
} }
// SMSAA // AMBIENT OCCLUSION
for( int i = 0; i < MAX_SSAO_BUFFERS; i++ )
{
globalFramebuffers.ambientOcclusionFBO[i] = new Framebuffer( va( "_aoRender%i", i ), glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
globalFramebuffers.ambientOcclusionFBO[i]->Bind();
globalFramebuffers.ambientOcclusionFBO[i]->AddColorBuffer( GL_RGBA8, 0 );
globalFramebuffers.ambientOcclusionFBO[i]->AttachImage2D( GL_TEXTURE_2D, globalImages->ambientOcclusionImage[i], 0 );
globalFramebuffers.ambientOcclusionFBO[i]->Check();
}
// SMAA
globalFramebuffers.smaaEdgesFBO = new Framebuffer( "_smaaEdges", glConfig.nativeScreenWidth, glConfig.nativeScreenHeight ); globalFramebuffers.smaaEdgesFBO = new Framebuffer( "_smaaEdges", glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
globalFramebuffers.smaaEdgesFBO->Bind(); globalFramebuffers.smaaEdgesFBO->Bind();
globalFramebuffers.smaaEdgesFBO->AddColorBuffer( GL_RGBA8, 0 ); globalFramebuffers.smaaEdgesFBO->AddColorBuffer( GL_RGBA8, 0 );
@ -213,19 +225,34 @@ void Framebuffer::CheckFramebuffers()
globalFramebuffers.hdrQuarterFBO->Check(); globalFramebuffers.hdrQuarterFBO->Check();
*/ */
// BLOOOM // BLOOM
for( int i = 0; i < 2; i++ )
for( int i = 0; i < MAX_BLOOM_BUFFERS; i++ )
{ {
globalImages->bloomRender[i]->Resize( glConfig.nativeScreenWidth / 4, glConfig.nativeScreenHeight / 4 ); globalImages->bloomRenderImage[i]->Resize( glConfig.nativeScreenWidth / 4, glConfig.nativeScreenHeight / 4 );
globalFramebuffers.bloomRenderFBO[i]->width = glConfig.nativeScreenWidth / 4; globalFramebuffers.bloomRenderFBO[i]->width = glConfig.nativeScreenWidth / 4;
globalFramebuffers.bloomRenderFBO[i]->height = glConfig.nativeScreenHeight / 4; globalFramebuffers.bloomRenderFBO[i]->height = glConfig.nativeScreenHeight / 4;
globalFramebuffers.bloomRenderFBO[i]->Bind(); globalFramebuffers.bloomRenderFBO[i]->Bind();
globalFramebuffers.bloomRenderFBO[i]->AttachImage2D( GL_TEXTURE_2D, globalImages->bloomRender[i], 0 ); globalFramebuffers.bloomRenderFBO[i]->AttachImage2D( GL_TEXTURE_2D, globalImages->bloomRenderImage[i], 0 );
globalFramebuffers.bloomRenderFBO[i]->Check(); globalFramebuffers.bloomRenderFBO[i]->Check();
} }
// AMBIENT OCCLUSION
for( int i = 0; i < MAX_SSAO_BUFFERS; i++ )
{
globalImages->ambientOcclusionImage[i]->Resize( glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
globalFramebuffers.ambientOcclusionFBO[i]->width = glConfig.nativeScreenWidth;
globalFramebuffers.ambientOcclusionFBO[i]->height = glConfig.nativeScreenHeight;
globalFramebuffers.ambientOcclusionFBO[i]->Bind();
globalFramebuffers.ambientOcclusionFBO[i]->AttachImage2D( GL_TEXTURE_2D, globalImages->ambientOcclusionImage[i], 0 );
globalFramebuffers.ambientOcclusionFBO[i]->Check();
}
// SMAA // SMAA
globalImages->smaaEdgesImage->Resize( glConfig.nativeScreenWidth, glConfig.nativeScreenHeight ); globalImages->smaaEdgesImage->Resize( glConfig.nativeScreenWidth, glConfig.nativeScreenHeight );
@ -257,12 +284,7 @@ void Framebuffer::Shutdown()
void Framebuffer::Bind() void Framebuffer::Bind()
{ {
#if 0 RENDERLOG_PRINTF( "Framebuffer::Bind( %s )\n", fboName.c_str() );
if( r_logFile.GetBool() )
{
RB_LogComment( "--- Framebuffer::Bind( name = '%s' ) ---\n", fboName.c_str() );
}
#endif
if( backEnd.glState.currentFramebuffer != this ) if( backEnd.glState.currentFramebuffer != this )
{ {
@ -278,6 +300,8 @@ bool Framebuffer::IsBound()
void Framebuffer::Unbind() void Framebuffer::Unbind()
{ {
RENDERLOG_PRINTF( "Framebuffer::Unbind()\n" );
//if(backEnd.glState.framebuffer != NULL) //if(backEnd.glState.framebuffer != NULL)
{ {
glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 );

View file

@ -31,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms
static const int MAX_SHADOWMAP_RESOLUTIONS = 5; static const int MAX_SHADOWMAP_RESOLUTIONS = 5;
static const int MAX_BLOOM_BUFFERS = 2; static const int MAX_BLOOM_BUFFERS = 2;
static const int MAX_SSAO_BUFFERS = 2;
#if 1 #if 1
static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 2048, 1024, 512, 512, 256 }; static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 2048, 1024, 512, 512, 256 };
@ -127,6 +128,7 @@ struct globalFramebuffers_t
// Framebuffer* hdrQuarterFBO; // Framebuffer* hdrQuarterFBO;
Framebuffer* hdr64FBO; Framebuffer* hdr64FBO;
Framebuffer* bloomRenderFBO[MAX_BLOOM_BUFFERS]; Framebuffer* bloomRenderFBO[MAX_BLOOM_BUFFERS];
Framebuffer* ambientOcclusionFBO[MAX_SSAO_BUFFERS];
Framebuffer* smaaEdgesFBO; Framebuffer* smaaEdgesFBO;
Framebuffer* smaaBlendFBO; Framebuffer* smaaBlendFBO;
}; };

View file

@ -357,7 +357,7 @@ public:
#endif #endif
idImage* currentRenderHDRImageQuarter; idImage* currentRenderHDRImageQuarter;
idImage* currentRenderHDRImage64; idImage* currentRenderHDRImage64;
idImage* bloomRender[2]; idImage* bloomRenderImage[2];
idImage* heatmap5Image; idImage* heatmap5Image;
idImage* heatmap7Image; idImage* heatmap7Image;
idImage* smaaInputImage; idImage* smaaInputImage;
@ -366,7 +366,7 @@ public:
idImage* smaaEdgesImage; idImage* smaaEdgesImage;
idImage* smaaBlendImage; idImage* smaaBlendImage;
idImage* currentNormalsImage; // cheap G-Buffer replacement, holds normals and surface roughness idImage* currentNormalsImage; // cheap G-Buffer replacement, holds normals and surface roughness
idImage* currentAOImage; // contains AO and bilateral filtering keys idImage* ambientOcclusionImage[2]; // contain AO and bilateral filtering keys
// RB end // RB end
idImage* scratchImage; idImage* scratchImage;
idImage* scratchImage2; idImage* scratchImage2;

View file

@ -847,8 +847,8 @@ void idImageManager::CreateIntrinsicImages()
currentRenderHDRImageQuarter = globalImages->ImageFromFunction( "_currentRenderHDRQuarter", R_HDR_RGBA16FImage_ResQuarter ); currentRenderHDRImageQuarter = globalImages->ImageFromFunction( "_currentRenderHDRQuarter", R_HDR_RGBA16FImage_ResQuarter );
currentRenderHDRImage64 = globalImages->ImageFromFunction( "_currentRenderHDR64", R_HDR_RGBA16FImage_Res64 ); currentRenderHDRImage64 = globalImages->ImageFromFunction( "_currentRenderHDR64", R_HDR_RGBA16FImage_Res64 );
bloomRender[0] = globalImages->ImageFromFunction( "_bloomRender0", R_HDR_RGBA16FImage_ResQuarter_Linear ); bloomRenderImage[0] = globalImages->ImageFromFunction( "_bloomRender0", R_HDR_RGBA16FImage_ResQuarter_Linear );
bloomRender[1] = globalImages->ImageFromFunction( "_bloomRender1", R_HDR_RGBA16FImage_ResQuarter_Linear ); bloomRenderImage[1] = globalImages->ImageFromFunction( "_bloomRender1", R_HDR_RGBA16FImage_ResQuarter_Linear );
heatmap5Image = ImageFromFunction( "_heatmap5", R_CreateHeatmap5ColorsImage ); heatmap5Image = ImageFromFunction( "_heatmap5", R_CreateHeatmap5ColorsImage );
heatmap7Image = ImageFromFunction( "_heatmap7", R_CreateHeatmap7ColorsImage ); heatmap7Image = ImageFromFunction( "_heatmap7", R_CreateHeatmap7ColorsImage );
@ -864,7 +864,8 @@ void idImageManager::CreateIntrinsicImages()
smaaBlendImage = globalImages->ImageFromFunction( "_smaaBlend", R_SMAAImage_ResNative ); smaaBlendImage = globalImages->ImageFromFunction( "_smaaBlend", R_SMAAImage_ResNative );
currentNormalsImage = ImageFromFunction( "_currentNormals", R_RGBA8Image ); currentNormalsImage = ImageFromFunction( "_currentNormals", R_RGBA8Image );
currentAOImage = ImageFromFunction( "_currentAO", R_RGBA8Image ); ambientOcclusionImage[0] = ImageFromFunction( "_ao0", R_SMAAImage_ResNative );
ambientOcclusionImage[1] = ImageFromFunction( "_ao1", R_SMAAImage_ResNative );
// RB end // RB end
// scratchImage is used for screen wipes/doublevision etc.. // scratchImage is used for screen wipes/doublevision etc..

View file

@ -514,7 +514,7 @@ void idRenderLog::LogCloseBlock( renderLogIndentLabel_t label )
{ {
closeBlockTime = Sys_Microseconds(); closeBlockTime = Sys_Microseconds();
assert( logLevel > 0 ); //assert( logLevel > 0 );
logLevel--; logLevel--;
Outdent( label ); Outdent( label );

View file

@ -150,6 +150,7 @@ void idRenderProgManager::Init()
{ BUILTIN_AMBIENT_OCCLUSION, "AmbientOcclusion_AO", "", 0, false }, { BUILTIN_AMBIENT_OCCLUSION, "AmbientOcclusion_AO", "", 0, false },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR, "AmbientOcclusion_blur", "", 0, false }, { BUILTIN_AMBIENT_OCCLUSION_BLUR, "AmbientOcclusion_blur", "", 0, false },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT, "AmbientOcclusion_blur", "_write", BIT( BRIGHTPASS ), false },
// RB end // RB end
{ BUILTIN_STEREO_DEGHOST, "stereoDeGhost.vfp", 0, false }, { BUILTIN_STEREO_DEGHOST, "stereoDeGhost.vfp", 0, false },
{ BUILTIN_STEREO_WARP, "stereoWarp.vfp", 0, false }, { BUILTIN_STEREO_WARP, "stereoWarp.vfp", 0, false },

View file

@ -463,6 +463,11 @@ public:
BindShader_Builtin( BUILTIN_AMBIENT_OCCLUSION_BLUR ); BindShader_Builtin( BUILTIN_AMBIENT_OCCLUSION_BLUR );
} }
void BindShader_AmbientOcclusionBlurAndOutput()
{
BindShader_Builtin( BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT );
}
#if 0 #if 0
void BindShader_ZCullReconstruct() void BindShader_ZCullReconstruct()
{ {
@ -588,6 +593,7 @@ protected:
BUILTIN_AMBIENT_OCCLUSION, BUILTIN_AMBIENT_OCCLUSION,
BUILTIN_AMBIENT_OCCLUSION_BLUR, BUILTIN_AMBIENT_OCCLUSION_BLUR,
BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT,
// RB end // RB end
BUILTIN_STEREO_DEGHOST, BUILTIN_STEREO_DEGHOST,
BUILTIN_STEREO_WARP, BUILTIN_STEREO_WARP,

View file

@ -4474,7 +4474,7 @@ static void RB_Bloom( const viewDef_t* viewDef )
globalFramebuffers.bloomRenderFBO[( j + 1 ) % 2 ]->Bind(); globalFramebuffers.bloomRenderFBO[( j + 1 ) % 2 ]->Bind();
glClear( GL_COLOR_BUFFER_BIT ); glClear( GL_COLOR_BUFFER_BIT );
globalImages->bloomRender[j % 2]->Bind(); globalImages->bloomRenderImage[j % 2]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
} }
@ -4488,7 +4488,7 @@ static void RB_Bloom( const viewDef_t* viewDef )
renderProgManager.BindShader_Screen(); renderProgManager.BindShader_Screen();
globalImages->bloomRender[( j + 1 ) % 2]->Bind(); globalImages->bloomRenderImage[( j + 1 ) % 2]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
@ -4521,6 +4521,8 @@ void RB_SSAO()
return; return;
} }
RENDERLOG_PRINTF( "---------- RB_SSAO() ----------\n" );
GL_CheckErrors(); GL_CheckErrors();
#if 0 #if 0
@ -4600,9 +4602,6 @@ void RB_SSAO()
//GL_State( GLS_DEPTHFUNC_ALWAYS ); //GL_State( GLS_DEPTHFUNC_ALWAYS );
//GL_Cull( CT_TWO_SIDED ); //GL_Cull( CT_TWO_SIDED );
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
GL_Cull( CT_TWO_SIDED );
int screenWidth = renderSystem->GetWidth(); int screenWidth = renderSystem->GetWidth();
int screenHeight = renderSystem->GetHeight(); int screenHeight = renderSystem->GetHeight();
@ -4610,6 +4609,16 @@ void RB_SSAO()
GL_Viewport( 0, 0, screenWidth, screenHeight ); GL_Viewport( 0, 0, screenWidth, screenHeight );
GL_Scissor( 0, 0, screenWidth, screenHeight ); GL_Scissor( 0, 0, screenWidth, screenHeight );
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
GL_Cull( CT_TWO_SIDED );
const bool hdrIsActive = ( r_useHDR.GetBool() && globalFramebuffers.hdrFBO != NULL && globalFramebuffers.hdrFBO->IsBound() );
globalFramebuffers.ambientOcclusionFBO[0]->Bind();
glClearColor( 1, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );
renderProgManager.BindShader_AmbientOcclusion(); renderProgManager.BindShader_AmbientOcclusion();
float screenCorrectionParm[4]; float screenCorrectionParm[4];
@ -4661,15 +4670,19 @@ void RB_SSAO()
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
float jitterTexScale[4];
// AO blur X // AO blur X
#if 1 #if 1
globalFramebuffers.ambientOcclusionFBO[1]->Bind();
renderProgManager.BindShader_AmbientOcclusionBlur(); renderProgManager.BindShader_AmbientOcclusionBlur();
const idScreenRect& viewport = backEnd.viewDef->viewport; //const idScreenRect& viewport = backEnd.viewDef->viewport;
globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); //globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
// set axis parameter // set axis parameter
float jitterTexScale[4];
jitterTexScale[0] = 1; jitterTexScale[0] = 1;
jitterTexScale[1] = 0; jitterTexScale[1] = 0;
jitterTexScale[2] = 0; jitterTexScale[2] = 0;
@ -4677,13 +4690,24 @@ void RB_SSAO()
SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale
GL_SelectTexture( 0 ); GL_SelectTexture( 0 );
globalImages->currentAOImage->Bind(); globalImages->ambientOcclusionImage[0]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
#endif
// AO blur Y // AO blur Y
globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() ); if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
}
else
{
Framebuffer::Unbind();
}
//globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
renderProgManager.BindShader_AmbientOcclusionBlurAndOutput();
// set axis parameter // set axis parameter
jitterTexScale[0] = 0; jitterTexScale[0] = 0;
@ -4693,10 +4717,11 @@ void RB_SSAO()
SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale
GL_SelectTexture( 0 ); GL_SelectTexture( 0 );
globalImages->currentAOImage->Bind(); globalImages->ambientOcclusionImage[1]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface ); RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
#endif
GL_CheckErrors(); GL_CheckErrors();
} }