Render environment probes to HDRA16F target

This commit is contained in:
Robert Beckebans 2021-03-14 15:59:02 +01:00
parent 71e2ea9aa3
commit 2b28723751
7 changed files with 142 additions and 57 deletions

View file

@ -56,13 +56,11 @@ public:
static void CheckFramebuffers();
// deletes OpenGL object but leaves structure intact for reloading
void PurgeFramebuffer();
void Bind();
bool IsBound();
static void Unbind();
static bool IsDefaultFramebufferActive();
static Framebuffer* GetActiveFramebuffer();
void AddColorBuffer( int format, int index, int multiSamples = 0 );
void AddDepthBuffer( int format, int multiSamples = 0 );

View file

@ -241,7 +241,8 @@ enum imageFileType_t
{
TGA,
PNG,
JPG
JPG,
EXR,
};
#include "BinaryImage.h"

View file

@ -378,6 +378,7 @@ void Framebuffer::Unbind()
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glBindRenderbuffer( GL_RENDERBUFFER, 0 );
tr.backend.currentFramebuffer = NULL;
}
}
@ -387,6 +388,11 @@ bool Framebuffer::IsDefaultFramebufferActive()
return ( tr.backend.currentFramebuffer == NULL );
}
Framebuffer* Framebuffer::GetActiveFramebuffer()
{
return tr.backend.currentFramebuffer;
}
void Framebuffer::AddColorBuffer( int format, int index, int multiSamples )
{
if( index < 0 || index >= glConfig.maxColorAttachments )

View file

@ -1407,6 +1407,7 @@ void idRenderBackend::GL_Clear( bool color, bool depth, bool stencil, byte stenc
glClear( clearFlags );
// RB begin
/*
if( r_useHDR.GetBool() && clearHDR && globalFramebuffers.hdrFBO != NULL )
{
bool isDefaultFramebufferActive = Framebuffer::IsDefaultFramebufferActive();
@ -1419,6 +1420,28 @@ void idRenderBackend::GL_Clear( bool color, bool depth, bool stencil, byte stenc
Framebuffer::Unbind();
}
}
*/
if( r_useHDR.GetBool() && clearHDR )
{
bool isDefaultFramebufferActive = Framebuffer::IsDefaultFramebufferActive();
if( viewDef && viewDef->renderView.rdflags & RDF_IRRADIANCE )
{
globalFramebuffers.envprobeFBO->Bind();
}
else
{
globalFramebuffers.hdrFBO->Bind();
}
glClear( clearFlags );
if( isDefaultFramebufferActive )
{
Framebuffer::Unbind();
}
}
// RB end
}

View file

@ -2078,7 +2078,7 @@ idRenderBackend::AmbientPass
*/
void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer )
{
const bool hdrIsActive = ( r_useHDR.GetBool() && globalFramebuffers.hdrFBO != NULL && globalFramebuffers.hdrFBO->IsBound() );
Framebuffer* previousFramebuffer = Framebuffer::GetActiveFramebuffer();
if( numDrawSurfs == 0 )
{
@ -2543,9 +2543,9 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
if( fillGbuffer )
{
// go back to main render target
if( hdrIsActive )
if( previousFramebuffer != NULL )
{
globalFramebuffers.hdrFBO->Bind();
previousFramebuffer->Bind();
}
else
{
@ -2945,6 +2945,11 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh
return;
}
if( viewDef->renderView.rdflags & RDF_NOSHADOWS )
{
return;
}
RENDERLOG_PRINTF( "---------- RB_ShadowMapPass( side = %i ) ----------\n", side );
renderProgManager.BindShader_Depth();
@ -3472,21 +3477,6 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh
DrawElementsWithCounters( drawSurf );
}
}
// cleanup the shadow specific rendering state
if( r_useHDR.GetBool() ) //&& !backEnd.viewDef->is2Dgui )
{
globalFramebuffers.hdrFBO->Bind();
}
else
{
Framebuffer::Unbind();
}
renderProgManager.Unbind();
GL_State( GLS_DEFAULT );
SetFragmentParm( RENDERPARM_ALPHA_TEST, vec4_zero.ToFloatPtr() );
}
/*
@ -3515,6 +3505,8 @@ void idRenderBackend::DrawInteractions( const viewDef_t* _viewDef )
const bool useLightDepthBounds = r_useLightDepthBounds.GetBool() && !r_useShadowMapping.GetBool();
Framebuffer* previousFramebuffer = Framebuffer::GetActiveFramebuffer();
//
// for each light, perform shadowing and adding
//
@ -3578,6 +3570,21 @@ void idRenderBackend::DrawInteractions( const viewDef_t* _viewDef )
ShadowMapPass( vLight->globalShadows, vLight, side );
}
// go back to main render target
if( previousFramebuffer != NULL )
{
previousFramebuffer->Bind();
}
else
{
Framebuffer::Unbind();
}
renderProgManager.Unbind();
GL_State( GLS_DEFAULT );
SetFragmentParm( RENDERPARM_ALPHA_TEST, vec4_zero.ToFloatPtr() );
// go back from light view to default camera view
ResetViewportAndScissorToDefaultCamera( _viewDef );
@ -4676,7 +4683,7 @@ void idRenderBackend::Tonemap( const viewDef_t* _viewDef )
void idRenderBackend::Bloom( const viewDef_t* _viewDef )
{
if( _viewDef->is2Dgui || !r_useHDR.GetBool() )
if( _viewDef->is2Dgui || !r_useHDR.GetBool() || ( _viewDef->renderView.rdflags & RDF_IRRADIANCE ) )
{
return;
}
@ -4822,13 +4829,18 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
return;
}
if( _viewDef->renderView.rdflags & RDF_NOAMBIENT )
{
return;
}
renderLog.OpenMainBlock( MRB_SSAO_PASS );
renderLog.OpenBlock( "Render_SSAO", colorBlue );
currentSpace = &viewDef->worldSpace;
RB_SetMVP( viewDef->worldSpace.mvp );
const bool hdrIsActive = ( r_useHDR.GetBool() && globalFramebuffers.hdrFBO != NULL && globalFramebuffers.hdrFBO->IsBound() );
Framebuffer* previousFramebuffer = Framebuffer::GetActiveFramebuffer();
int screenWidth = renderSystem->GetWidth();
int screenHeight = renderSystem->GetHeight();
@ -4920,9 +4932,9 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_ALPHAMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
}
if( hdrIsActive )
if( previousFramebuffer != NULL )
{
globalFramebuffers.hdrFBO->Bind();
previousFramebuffer->Bind();
}
else
{
@ -5049,9 +5061,9 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
// AO blur Y
if( downModulateScreen )
{
if( hdrIsActive )
if( previousFramebuffer != NULL )
{
globalFramebuffers.hdrFBO->Bind();
previousFramebuffer->Bind();
}
else
{
@ -5086,9 +5098,9 @@ void idRenderBackend::DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef
if( !downModulateScreen )
{
// go back to main scene render target
if( hdrIsActive )
if( previousFramebuffer != NULL )
{
globalFramebuffers.hdrFBO->Bind();
previousFramebuffer->Bind();
}
else
{
@ -5133,12 +5145,17 @@ void idRenderBackend::DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewD
return;
}
if( _viewDef->renderView.rdflags & RDF_NOAMBIENT )
{
return;
}
RENDERLOG_PRINTF( "---------- RB_SSGI() ----------\n" );
currentSpace = &viewDef->worldSpace;
RB_SetMVP( viewDef->worldSpace.mvp );
const bool hdrIsActive = ( r_useHDR.GetBool() && globalFramebuffers.hdrFBO != NULL && globalFramebuffers.hdrFBO->IsBound() );
Framebuffer* previousFramebuffer = Framebuffer::GetActiveFramebuffer();
int screenWidth = renderSystem->GetWidth();
int screenHeight = renderSystem->GetHeight();
@ -5147,7 +5164,8 @@ void idRenderBackend::DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewD
GL_Viewport( 0, 0, screenWidth, screenHeight );
GL_Scissor( 0, 0, screenWidth, screenHeight );
if( !hdrIsActive )
// TODO remove
if( previousFramebuffer == NULL )
{
const idScreenRect& viewport = viewDef->viewport;
globalImages->currentRenderImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
@ -5237,9 +5255,9 @@ void idRenderBackend::DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewD
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
}
if( hdrIsActive )
if( previousFramebuffer != NULL )
{
globalFramebuffers.hdrFBO->Bind();
previousFramebuffer->Bind();
}
else
{
@ -5301,9 +5319,9 @@ void idRenderBackend::DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewD
}
GL_SelectTexture( 2 );
if( hdrIsActive )
if( previousFramebuffer != NULL )
{
globalImages->currentRenderHDRImage->Bind();
previousFramebuffer->Bind();
}
else
{
@ -5336,9 +5354,9 @@ void idRenderBackend::DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewD
#endif
// AO blur Y
if( hdrIsActive )
if( previousFramebuffer != NULL )
{
globalFramebuffers.hdrFBO->Bind();
previousFramebuffer->Bind();
}
else
{
@ -5539,7 +5557,14 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
if( useHDR )
{
globalFramebuffers.hdrFBO->Bind();
if( _viewDef->renderView.rdflags & RDF_IRRADIANCE )
{
globalFramebuffers.envprobeFBO->Bind();
}
else
{
globalFramebuffers.hdrFBO->Bind();
}
}
else
{
@ -5710,8 +5735,9 @@ void idRenderBackend::DrawViewInternal( const viewDef_t* _viewDef, const int ste
DBG_RenderDebugTools( drawSurfs, numDrawSurfs );
#if !defined(USE_VULKAN)
// RB: convert back from HDR to LDR range
if( useHDR )
if( useHDR && !( _viewDef->renderView.rdflags & RDF_IRRADIANCE ) )
{
/*
int x = backEnd.viewDef->viewport.x1;

View file

@ -304,7 +304,7 @@ idCVar r_showViewEnvprobes( "r_showViewEnvprobes", "0", CVAR_RENDERER | CVAR_INT
idCVar r_exposure( "r_exposure", "0.5", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_FLOAT, "HDR exposure or LDR brightness [0.0 .. 1.0]", 0.0f, 1.0f );
// RB end
const char* fileExten[3] = { "tga", "png", "jpg" };
const char* fileExten[4] = { "tga", "png", "jpg", "exr" };
const char* envDirection[6] = { "_px", "_nx", "_py", "_ny", "_pz", "_nz" };
const char* skyDirection[6] = { "_forward", "_back", "_left", "_right", "_up", "_down" };
@ -731,7 +731,17 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref =
// include extra space for OpenGL padding to word boundaries
int sysWidth = renderSystem->GetWidth();
int sysHeight = renderSystem->GetHeight();
byte* temp = ( byte* )R_StaticAlloc( ( sysWidth + 3 ) * sysHeight * 3 );
byte* temp = NULL;
if( ref && ref->rdflags & RDF_IRRADIANCE )
{
// * 2 = sizeof( half float )
temp = ( byte* )R_StaticAlloc( RADIANCE_CUBEMAP_SIZE * RADIANCE_CUBEMAP_SIZE * 3 * 2 );
}
else
{
temp = ( byte* )R_StaticAlloc( ( sysWidth + 3 ) * sysHeight * 3 );
}
// foresthale 2014-03-01: fixed custom screenshot resolution by doing a more direct render path
#ifdef BUGFIXEDSCREENSHOTRESOLUTION
@ -821,15 +831,27 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref =
h = height - yo;
}
glReadBuffer( GL_FRONT );
glReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, temp );
int row = ( w * 3 + 3 ) & ~3; // OpenGL pads to dword boundaries
for( int y = 0 ; y < h ; y++ )
if( ref && ref->rdflags & RDF_IRRADIANCE )
{
memcpy( buffer + ( ( yo + y )* width + xo ) * 3,
temp + y * row, w * 3 );
globalFramebuffers.envprobeFBO->Bind();
glPixelStorei( GL_PACK_ROW_LENGTH, RADIANCE_CUBEMAP_SIZE );
glReadPixels( 0, 0, w, h, GL_RGB, GL_HALF_FLOAT, buffer );
Framebuffer::Unbind();
}
else
{
glReadBuffer( GL_FRONT );
glReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, temp );
int row = ( w * 3 + 3 ) & ~3; // OpenGL pads to dword boundaries
for( int y = 0 ; y < h ; y++ )
{
memcpy( buffer + ( ( yo + y )* width + xo ) * 3,
temp + y * row, w * 3 );
}
}
}
}
@ -874,7 +896,11 @@ void idRenderSystemLocal::TakeScreenshot( int width, int height, const char* fil
int pix = width * height;
const int bufferSize = pix * 3 + 18;
if( exten == PNG )
if( exten == EXR )
{
buffer = ( byte* )R_StaticAlloc( pix * 3 * 2 );
}
else if( exten == PNG )
{
buffer = ( byte* )R_StaticAlloc( pix * 3 );
}
@ -886,7 +912,7 @@ void idRenderSystemLocal::TakeScreenshot( int width, int height, const char* fil
if( blends <= 1 )
{
if( exten == PNG )
if( exten == PNG || exten == EXR )
{
R_ReadTiledPixels( width, height, buffer, ref );
}
@ -944,7 +970,12 @@ void idRenderSystemLocal::TakeScreenshot( int width, int height, const char* fil
r_jitter.SetBool( false );
}
if( exten == PNG )
if( exten == EXR )
{
R_WriteEXR( finalFileName, buffer, 3, width, height, "fs_basepath" );
//R_WritePNG( finalFileName, buffer, 3, width, height, false, "fs_basepath" );
}
else if( exten == PNG )
{
R_WritePNG( finalFileName, buffer, 3, width, height, false, "fs_basepath" );
}

View file

@ -954,16 +954,16 @@ CONSOLE_COMMAND( generateEnvironmentProbes, "Generate environment probes", NULL
{
ref = primary.renderView;
extension = envDirection[ j ];
ref.rdflags = RDF_NOAMBIENT | RDF_IRRADIANCE;
ref.fov_x = ref.fov_y = 90;
ref.vieworg = def->parms.origin;
ref.viewaxis = axis[j];
extension = envDirection[ j ];
fullname.Format( "env/%s/envprobe%i%s", baseName.c_str(), i, extension );
// TODO capture resolved HDR data without bloom aka _currentRender in 16bit float HDR RGB
tr.TakeScreenshot( size, size, fullname, blends, &ref, PNG );
tr.TakeScreenshot( size, size, fullname, blends, &ref, EXR );
//tr.CaptureRenderToFile( fullname, false );
}
}