Several bugfixes that address cubemap processing for SH/GGX data

This commit is contained in:
Robert Beckebans 2021-05-03 20:36:26 +02:00
parent 7d5c840ec3
commit c119cf3513
10 changed files with 59 additions and 52 deletions

View file

@ -384,8 +384,10 @@ void main( PS_IN fragment, out PS_OUT result )
// evaluate specular IBL
// should be 8 = numMips - 1, 256^2 = 9 mips
const float MAX_REFLECTION_LOD = 8.0;
// 512^2 = 10 mips
// however we can't use the last 3 mips with octahedrons because the quality suffers too much
// so it is 7 - 1
const float MAX_REFLECTION_LOD = 6.0;
float mip = clamp( ( roughness * MAX_REFLECTION_LOD ), 0.0, MAX_REFLECTION_LOD );
//float mip = 0.0;

View file

@ -265,8 +265,10 @@ void main( PS_IN fragment, out PS_OUT result )
// evaluate specular IBL
// should be 8 = numMips - 1, 256^2 = 9 mips
const float MAX_REFLECTION_LOD = 8.0;
// 512^2 = 10 mips
// however we can't use the last 3 mips with octahedrons because the quality suffers too much
// so it is 7 - 1
const float MAX_REFLECTION_LOD = 6.0;
float mip = clamp( ( roughness * MAX_REFLECTION_LOD ), 0.0, MAX_REFLECTION_LOD );
//float mip = 0.0;

View file

@ -34,8 +34,9 @@ static const int MAX_BLOOM_BUFFERS = 2;
static const int MAX_SSAO_BUFFERS = 2;
static const int MAX_HIERARCHICAL_ZBUFFERS = 6; // native resolution + 5 MIP LEVELS
static const int RADIANCE_CUBEMAP_SIZE = 256;
static const int IRRADIANCE_CUBEMAP_SIZE = 30 + 2;
static const int ENVPROBE_CAPTURE_SIZE = 256;
static const int RADIANCE_OCTAHEDRON_SIZE = 512;
static const int IRRADIANCE_OCTAHEDRON_SIZE = 30 + 2;
#if 1
static int shadowMapResolutions[MAX_SHADOWMAP_RESOLUTIONS] = { 2048, 1024, 512, 512, 256 };

View file

@ -267,12 +267,12 @@ static void R_HDR_RGBA16FImage_Res64( idImage* image )
static void R_EnvprobeImage_HDR( idImage* image )
{
image->GenerateImage( NULL, RADIANCE_CUBEMAP_SIZE, RADIANCE_CUBEMAP_SIZE, TF_NEAREST, TR_CLAMP, TD_RGBA16F );
image->GenerateImage( NULL, ENVPROBE_CAPTURE_SIZE, ENVPROBE_CAPTURE_SIZE, TF_NEAREST, TR_CLAMP, TD_RGBA16F );
}
static void R_EnvprobeImage_Depth( idImage* image )
{
image->GenerateImage( NULL, RADIANCE_CUBEMAP_SIZE, RADIANCE_CUBEMAP_SIZE, TF_NEAREST, TR_CLAMP, TD_DEPTH );
image->GenerateImage( NULL, ENVPROBE_CAPTURE_SIZE, ENVPROBE_CAPTURE_SIZE, TF_NEAREST, TR_CLAMP, TD_DEPTH );
}
static void R_SMAAImage_ResNative( idImage* image )

View file

@ -135,7 +135,7 @@ void Framebuffer::Init()
// HDR CUBEMAP CAPTURE
globalFramebuffers.envprobeFBO = new Framebuffer( "_envprobeRender", RADIANCE_CUBEMAP_SIZE, RADIANCE_CUBEMAP_SIZE );
globalFramebuffers.envprobeFBO = new Framebuffer( "_envprobeRender", ENVPROBE_CAPTURE_SIZE, ENVPROBE_CAPTURE_SIZE );
globalFramebuffers.envprobeFBO->Bind();
globalFramebuffers.envprobeFBO->AddColorBuffer( GL_RGBA16F, 0 );

View file

@ -1824,9 +1824,7 @@ void idRenderBackend::DBG_ShowViewEnvprobes()
#endif
}
//if( r_showViewEnvprobes.GetInteger() >= 3 )
if( tr.primaryWorld )
if( tr.primaryWorld && r_showViewEnvprobes.GetInteger() == 3 )
{
/*
idList<viewEnvprobe_t*, TAG_RENDER_ENVPROBE> viewEnvprobes;

View file

@ -5032,8 +5032,10 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
" // evaluate specular IBL\n"
"\n"
" // should be 8 = numMips - 1, 256^2 = 9 mips\n"
" const float MAX_REFLECTION_LOD = 8.0;\n"
" // 512^2 = 10 mips\n"
" // however we can't use the last 3 mips with octahedrons because the quality suffers too much\n"
" // so it is 7 - 1\n"
" const float MAX_REFLECTION_LOD = 6.0;\n"
" float mip = clamp( ( roughness * MAX_REFLECTION_LOD ), 0.0, MAX_REFLECTION_LOD );\n"
" //float mip = 0.0;\n"
"\n"
@ -5671,8 +5673,10 @@ static const cgShaderDef_t cg_renderprogs[] =
"\n"
" // evaluate specular IBL\n"
"\n"
" // should be 8 = numMips - 1, 256^2 = 9 mips\n"
" const float MAX_REFLECTION_LOD = 8.0;\n"
" // 512^2 = 10 mips\n"
" // however we can't use the last 3 mips with octahedrons because the quality suffers too much\n"
" // so it is 7 - 1\n"
" const float MAX_REFLECTION_LOD = 6.0;\n"
" float mip = clamp( ( roughness * MAX_REFLECTION_LOD ), 0.0, MAX_REFLECTION_LOD );\n"
" //float mip = 0.0;\n"
"\n"

View file

@ -291,9 +291,9 @@ idCVar r_ldrContrastOffset( "r_ldrContrastOffset", "3", CVAR_RENDERER | CVAR_FLO
idCVar r_useFilmicPostProcessing( "r_useFilmicPostProcessing", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "apply several post process effects to mimic a filmic look" );
#if defined( USE_VULKAN )
idCVar r_forceAmbient( "r_forceAmbient", "0.4", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "render additional ambient pass to make the game less dark", 0.0f, 0.75f );
idCVar r_forceAmbient( "r_forceAmbient", "0.5", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "render additional ambient pass to make the game less dark", 0.0f, 0.75f );
#else
idCVar r_forceAmbient( "r_forceAmbient", "0.4", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "render additional ambient pass to make the game less dark", 0.0f, 0.75f );
idCVar r_forceAmbient( "r_forceAmbient", "0.5", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "render additional ambient pass to make the game less dark", 0.0f, 1.0f );
#endif
idCVar r_useSSGI( "r_useSSGI", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use screen space global illumination and reflections" );
@ -753,7 +753,7 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref =
if( ref && ref->rdflags & RDF_IRRADIANCE )
{
// * 2 = sizeof( half float )
//temp = ( byte* )R_StaticAlloc( RADIANCE_CUBEMAP_SIZE * RADIANCE_CUBEMAP_SIZE * 3 * 2 );
//temp = ( byte* )R_StaticAlloc( ENVPROBE_CAPTURE_SIZE * ENVPROBE_CAPTURE_SIZE * 3 * 2 );
}
else
{
@ -856,7 +856,7 @@ void R_ReadTiledPixels( int width, int height, byte* buffer, renderView_t* ref =
{
globalFramebuffers.envprobeFBO->Bind();
glPixelStorei( GL_PACK_ROW_LENGTH, RADIANCE_CUBEMAP_SIZE );
glPixelStorei( GL_PACK_ROW_LENGTH, ENVPROBE_CAPTURE_SIZE );
glReadPixels( 0, 0, w, h, GL_RGB, GL_HALF_FLOAT, buffer );
R_VerticalFlipRGB16F( buffer, w, h );

View file

@ -593,13 +593,10 @@ void CalculateIrradianceJob( calcEnvprobeParms_t* parms )
buffers[ i ] = ( halfFloat_t* ) parms->radiance[ i ];
}
const float invDstSize = 1.0f / float( parms->outHeight );
const float invDstSize = 1.0f / float( ENVPROBE_CAPTURE_SIZE );
const idVec2i sourceImageSize( ENVPROBE_CAPTURE_SIZE, ENVPROBE_CAPTURE_SIZE );
const int numMips = idMath::BitsForInteger( parms->outHeight );
const idVec2i sourceImageSize( parms->outHeight, parms->outHeight );
CommandlineProgressBar progressBar( R_CalculateUsedAtlasPixels( sourceImageSize.y ), parms->printWidth, parms->printHeight );
CommandlineProgressBar progressBar( R_CalculateUsedAtlasPixels( parms->outHeight ), parms->printWidth, parms->printHeight );
if( parms->printProgress )
{
progressBar.Start();
@ -628,7 +625,7 @@ void CalculateIrradianceJob( calcEnvprobeParms_t* parms )
float u, v;
idVec3 radiance;
R_SampleCubeMapHDR16F( dir, parms->outHeight, buffers, &radiance[0], u, v );
R_SampleCubeMapHDR16F( dir, ENVPROBE_CAPTURE_SIZE, buffers, &radiance[0], u, v );
//radiance = dir * 0.5 + idVec3( 0.5f, 0.5f, 0.5f );
@ -669,10 +666,10 @@ void CalculateIrradianceJob( calcEnvprobeParms_t* parms )
}
}
const int numMips = idMath::BitsForInteger( parms->outHeight );
for( int mip = 0; mip < numMips; mip++ )
{
float roughness = ( float )mip / ( float )( numMips - 1 );
idVec4 dstRect = R_CalculateMipRect( parms->outHeight, mip );
for( int x = dstRect.x; x < ( dstRect.x + dstRect.z ); x++ )
@ -760,10 +757,9 @@ void CalculateRadianceJob( calcEnvprobeParms_t* parms )
const float invDstSize = 1.0f / float( parms->outHeight );
const int numMips = idMath::BitsForInteger( parms->outHeight );
const int numOctahedronMips = numMips - 3; // the last 3 mips are too low quality for filtering
const idVec2i sourceImageSize( parms->outHeight, parms->outHeight );
CommandlineProgressBar progressBar( R_CalculateUsedAtlasPixels( sourceImageSize.y ), parms->printWidth, parms->printHeight );
CommandlineProgressBar progressBar( R_CalculateUsedAtlasPixels( parms->outHeight ), parms->printWidth, parms->printHeight );
if( parms->printProgress )
{
progressBar.Start();
@ -780,9 +776,9 @@ void CalculateRadianceJob( calcEnvprobeParms_t* parms )
}
}
for( int mip = 0; mip < numMips; mip++ )
for( int mip = 0; mip < numOctahedronMips; mip++ )
{
float roughness = ( float )mip / ( float )( numMips - 1 );
float roughness = ( float )mip / ( float )( numOctahedronMips - 1 );
idVec4 dstRect = R_CalculateMipRect( parms->outHeight, mip );
@ -830,7 +826,7 @@ void CalculateRadianceJob( calcEnvprobeParms_t* parms )
float sample[3];
float u, v;
R_SampleCubeMapHDR16F( H, parms->outHeight, buffers, sample, u, v );
R_SampleCubeMapHDR16F( H, ENVPROBE_CAPTURE_SIZE, buffers, sample, u, v );
outColor[0] += sample[0] * NdotL;
outColor[1] += sample[1] * NdotL;
@ -941,7 +937,7 @@ CONSOLE_COMMAND( bakeEnvironmentProbes, "Bake environment probes", NULL )
baseName = tr.primaryWorld->mapName;
baseName.StripFileExtension();
captureSize = RADIANCE_CUBEMAP_SIZE;
captureSize = ENVPROBE_CAPTURE_SIZE;
if( !tr.primaryView )
{
@ -997,6 +993,8 @@ CONSOLE_COMMAND( bakeEnvironmentProbes, "Bake environment probes", NULL )
CommandlineProgressBar progressBar( totalProcessedProbes, sysWidth, sysHeight );
progressBar.Start();
int start = Sys_Milliseconds();
for( int i = 0; i < tr.primaryWorld->envprobeDefs.Num(); i++ )
{
RenderEnvprobeLocal* def = tr.primaryWorld->envprobeDefs[i];
@ -1055,7 +1053,7 @@ CONSOLE_COMMAND( bakeEnvironmentProbes, "Bake environment probes", NULL )
globalFramebuffers.envprobeFBO->Bind();
glPixelStorei( GL_PACK_ROW_LENGTH, RADIANCE_CUBEMAP_SIZE );
glPixelStorei( GL_PACK_ROW_LENGTH, ENVPROBE_CAPTURE_SIZE );
glReadPixels( 0, 0, captureSize, captureSize, GL_RGB, GL_HALF_FLOAT, float16FRGB );
R_VerticalFlipRGB16F( float16FRGB, captureSize, captureSize );
@ -1074,10 +1072,12 @@ CONSOLE_COMMAND( bakeEnvironmentProbes, "Bake environment probes", NULL )
fullname.Format( "%s/envprobe%i", baseName.c_str(), i );
// create 2 jobs
R_MakeAmbientMap( fullname.c_str(), buffers, "_amb", IRRADIANCE_CUBEMAP_SIZE, false, useThreads );
R_MakeAmbientMap( fullname.c_str(), buffers, "_spec", RADIANCE_CUBEMAP_SIZE, true, useThreads );
R_MakeAmbientMap( fullname.c_str(), buffers, "_amb", IRRADIANCE_OCTAHEDRON_SIZE, false, useThreads );
R_MakeAmbientMap( fullname.c_str(), buffers, "_spec", RADIANCE_OCTAHEDRON_SIZE, true, useThreads );
}
int end = Sys_Milliseconds();
tr.takingEnvprobe = false;
// restore the original resolution, same as "vid_restart"
@ -1090,6 +1090,8 @@ CONSOLE_COMMAND( bakeEnvironmentProbes, "Bake environment probes", NULL )
r_useParallelAddShadows.SetBool( true );
r_useParallelAddLights.SetBool( true );
common->Printf( "captured environemt probes %5.1f seconds\n\n", ( end - start ) * 0.001f );
if( useThreads )
{
idLib::Printf( "Processing probes on all available cores... Please wait.\n" );

View file

@ -908,11 +908,8 @@ void CalculateLightGridPointJob( calcLightGridPointParms_t* parms )
buffers[ i ] = ( halfFloat_t* ) parms->radiance[ i ];
}
const float invDstSize = 1.0f / float( parms->outHeight );
const int numMips = idMath::BitsForInteger( parms->outHeight );
const idVec2i sourceImageSize( parms->outHeight, parms->outHeight );
const float invDstSize = 1.0f / float( ENVPROBE_CAPTURE_SIZE );
const idVec2i sourceImageSize( ENVPROBE_CAPTURE_SIZE, ENVPROBE_CAPTURE_SIZE );
// build L4 Spherical Harmonics from source image
SphericalHarmonicsT<idVec3, 4> shRadiance;
@ -935,7 +932,7 @@ void CalculateLightGridPointJob( calcLightGridPointParms_t* parms )
float u, v;
idVec3 radiance;
R_SampleCubeMapHDR16F( dir, parms->outHeight, buffers, &radiance[0], u, v );
R_SampleCubeMapHDR16F( dir, ENVPROBE_CAPTURE_SIZE, buffers, &radiance[0], u, v );
//radiance = dir * 0.5 + idVec3( 0.5f, 0.5f, 0.5f );
@ -1049,12 +1046,12 @@ CONSOLE_COMMAND( bakeLightGrids, "Bake irradiance/vis light grid data", NULL )
int sysWidth = renderSystem->GetWidth();
int sysHeight = renderSystem->GetHeight();
bool useThreads = false;
bool useThreads = true;
baseName = tr.primaryWorld->mapName;
baseName.StripFileExtension();
captureSize = RADIANCE_CUBEMAP_SIZE;
captureSize = ENVPROBE_CAPTURE_SIZE;
blends = 1;
int limit = MAX_AREA_LIGHTGRID_POINTS;
@ -1098,10 +1095,7 @@ CONSOLE_COMMAND( bakeLightGrids, "Bake irradiance/vis light grid data", NULL )
totalProcessedProbes += numGridPoints;
CommandlineProgressBar progressBar( numGridPoints, sysWidth, sysHeight );
if( !useThreads )
{
progressBar.Start();
}
progressBar.Start();
int start = Sys_Milliseconds();
@ -1210,7 +1204,7 @@ CONSOLE_COMMAND( bakeLightGrids, "Bake irradiance/vis light grid data", NULL )
globalFramebuffers.envprobeFBO->Bind();
glPixelStorei( GL_PACK_ROW_LENGTH, RADIANCE_CUBEMAP_SIZE );
glPixelStorei( GL_PACK_ROW_LENGTH, ENVPROBE_CAPTURE_SIZE );
glReadPixels( 0, 0, captureSize, captureSize, GL_RGB, GL_HALF_FLOAT, float16FRGB );
R_VerticalFlipRGB16F( float16FRGB, captureSize, captureSize );
@ -1282,6 +1276,10 @@ CONSOLE_COMMAND( bakeLightGrids, "Bake irradiance/vis light grid data", NULL )
if( useThreads )
{
idLib::Printf( "Processing probes on all available cores... Please wait.\n" );
common->UpdateScreen( false );
common->UpdateScreen( false );
//tr.envprobeJobList->Submit();
tr.envprobeJobList->Submit( NULL, JOBLIST_PARALLELISM_MAX_CORES );
tr.envprobeJobList->Wait();