From f1e54f249b473696511cfa6bb0ca7019bc27a246 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Tue, 13 Apr 2021 19:53:02 +0200 Subject: [PATCH] Splitted light grid up into multiple for each BSP area --- neo/renderer/OpenGL/RenderDebug_GL.cpp | 127 ++++++++++++++----------- neo/renderer/RenderCommon.h | 1 + neo/renderer/RenderWorld_lightgrid.cpp | 116 ++++++++++++++-------- neo/renderer/RenderWorld_local.h | 12 ++- 4 files changed, 158 insertions(+), 98 deletions(-) diff --git a/neo/renderer/OpenGL/RenderDebug_GL.cpp b/neo/renderer/OpenGL/RenderDebug_GL.cpp index 14c32a04..cf58cca2 100644 --- a/neo/renderer/OpenGL/RenderDebug_GL.cpp +++ b/neo/renderer/OpenGL/RenderDebug_GL.cpp @@ -1794,8 +1794,8 @@ void idRenderBackend::DBG_ShowLightGrid() } // all volumes are expressed in world coordinates - //renderProgManager.BindShader_Color(); - renderProgManager.BindShader_Octahedron(); + renderProgManager.BindShader_Color(); + //renderProgManager.BindShader_Octahedron(); GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_DEPTHMASK ); GL_Color( 1.0f, 1.0f, 1.0f ); @@ -1803,85 +1803,102 @@ void idRenderBackend::DBG_ShowLightGrid() idMat3 axis; axis.Identity(); - for( int i = 0; i < tr.primaryWorld->lightGrid.lightGridPoints.Num(); i++ ) + //for( int a = 0; a < tr.primaryWorld->NumAreas(); a++ ) + + // only show current area + int a = tr.primaryWorld->PointInArea( viewDef->renderView.vieworg ); + if( a == -1 ) { - lightGridPoint_t* gridPoint = &tr.primaryWorld->lightGrid.lightGridPoints[i]; + return; + } - idVec3 distanceToCam = gridPoint->origin - viewDef->renderView.vieworg; - if( distanceToCam.LengthSqr() > ( 1024 * 1024 ) ) + { + portalArea_t* area = &tr.primaryWorld->portalAreas[a]; + + for( int i = 0; i < area->lightGrid.lightGridPoints.Num(); i++ ) { - continue; - } + lightGridPoint_t* gridPoint = &area->lightGrid.lightGridPoints[i]; + if( !gridPoint->valid ) + { + continue; + } - /* - idVec4 c; - c[0] = idMath::ClampFloat( 0, 1, gridPoint->directed[0] * ( 1.0f / 255.0f ) ); - c[1] = idMath::ClampFloat( 0, 1, gridPoint->directed[1] * ( 1.0f / 255.0f ) ); - c[2] = idMath::ClampFloat( 0, 1, gridPoint->directed[2] * ( 1.0f / 255.0f ) ); + idVec3 distanceToCam = gridPoint->origin - viewDef->renderView.vieworg; + if( distanceToCam.LengthSqr() > ( 1024 * 1024 ) ) + { + continue; + } - glColor4f( c[0], c[1], c[2], 1 ); + /* + idVec4 c; + c[0] = idMath::ClampFloat( 0, 1, gridPoint->directed[0] * ( 1.0f / 255.0f ) ); + c[1] = idMath::ClampFloat( 0, 1, gridPoint->directed[1] * ( 1.0f / 255.0f ) ); + c[2] = idMath::ClampFloat( 0, 1, gridPoint->directed[2] * ( 1.0f / 255.0f ) ); - float lattitude = DEG2RAD( gridPoint->latLong[1] * ( 360.0f / 255.0f ) ); - float longitude = DEG2RAD( gridPoint->latLong[0] * ( 360.0f / 255.0f ) ); + glColor4f( c[0], c[1], c[2], 1 ); - idVec3 dir; - dir[0] = idMath::Cos( lattitude ) * idMath::Sin( longitude ); - dir[1] = idMath::Sin( lattitude ) * idMath::Sin( longitude ); - dir[2] = idMath::Cos( longitude ); + float lattitude = DEG2RAD( gridPoint->latLong[1] * ( 360.0f / 255.0f ) ); + float longitude = DEG2RAD( gridPoint->latLong[0] * ( 360.0f / 255.0f ) ); - idVec3 pos2 = gridPoint->origin - dir * r_showLightGrid.GetFloat(); + idVec3 dir; + dir[0] = idMath::Cos( lattitude ) * idMath::Sin( longitude ); + dir[1] = idMath::Sin( lattitude ) * idMath::Sin( longitude ); + dir[2] = idMath::Cos( longitude ); - glBegin( GL_LINES ); + idVec3 pos2 = gridPoint->origin - dir * r_showLightGrid.GetFloat(); - glColor4f( c[0], c[1], c[2], 1 ); - //glColor4f( 1, 1, 1, 1 ); - glVertex3fv( gridPoint->origin.ToFloatPtr() ); + glBegin( GL_LINES ); - glColor4f( 0, 0, 0, 1 ); - glVertex3fv( pos2.ToFloatPtr() ); - glEnd(); - */ + glColor4f( c[0], c[1], c[2], 1 ); + //glColor4f( 1, 1, 1, 1 ); + glVertex3fv( gridPoint->origin.ToFloatPtr() ); + + glColor4f( 0, 0, 0, 1 ); + glVertex3fv( pos2.ToFloatPtr() ); + glEnd(); + */ #if 1 - idVec4 localViewOrigin( 1.0f ); - idVec4 globalViewOrigin; - globalViewOrigin.x = viewDef->renderView.vieworg.x; - globalViewOrigin.y = viewDef->renderView.vieworg.y; - globalViewOrigin.z = viewDef->renderView.vieworg.z; - globalViewOrigin.w = 1.0f; + idVec4 localViewOrigin( 1.0f ); + idVec4 globalViewOrigin; + globalViewOrigin.x = viewDef->renderView.vieworg.x; + globalViewOrigin.y = viewDef->renderView.vieworg.y; + globalViewOrigin.z = viewDef->renderView.vieworg.z; + globalViewOrigin.w = 1.0f; - float modelMatrix[16]; - R_AxisToModelMatrix( axis, gridPoint->origin, modelMatrix ); + float modelMatrix[16]; + R_AxisToModelMatrix( axis, gridPoint->origin, modelMatrix ); - R_GlobalPointToLocal( modelMatrix, viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); + R_GlobalPointToLocal( modelMatrix, viewDef->renderView.vieworg, localViewOrigin.ToVec3() ); - renderProgManager.SetUniformValue( RENDERPARM_LOCALVIEWORIGIN, localViewOrigin.ToFloatPtr() ); // rpLocalViewOrigin + renderProgManager.SetUniformValue( RENDERPARM_LOCALVIEWORIGIN, localViewOrigin.ToFloatPtr() ); // rpLocalViewOrigin #endif -#if 0 - idVec3 color = tr.primaryWorld->lightGrid.GetProbeIndexDebugColor( i ); - GL_Color( color ); +#if 1 + idVec3 color = area->lightGrid.GetProbeIndexDebugColor( i ); + GL_Color( color ); #else - GL_SelectTexture( 0 ); - gridPoint->irradianceImage->Bind(); + GL_SelectTexture( 0 ); + gridPoint->irradianceImage->Bind(); #endif - idRenderMatrix modelRenderMatrix; - idRenderMatrix::CreateFromOriginAxis( gridPoint->origin, axis, modelRenderMatrix ); + idRenderMatrix modelRenderMatrix; + idRenderMatrix::CreateFromOriginAxis( gridPoint->origin, axis, modelRenderMatrix ); - // calculate the matrix that transforms the unit cube to exactly cover the model in world space - const float size = 3.0f; - idBounds debugBounds( idVec3( -size ), idVec3( size ) ); + // calculate the matrix that transforms the unit cube to exactly cover the model in world space + const float size = 3.0f; + idBounds debugBounds( idVec3( -size ), idVec3( size ) ); - idRenderMatrix inverseBaseModelProject; - idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, debugBounds, inverseBaseModelProject ); + idRenderMatrix inverseBaseModelProject; + idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, debugBounds, inverseBaseModelProject ); - idRenderMatrix invProjectMVPMatrix; - idRenderMatrix::Multiply( viewDef->worldSpace.mvp, inverseBaseModelProject, invProjectMVPMatrix ); - RB_SetMVP( invProjectMVPMatrix ); + idRenderMatrix invProjectMVPMatrix; + idRenderMatrix::Multiply( viewDef->worldSpace.mvp, inverseBaseModelProject, invProjectMVPMatrix ); + RB_SetMVP( invProjectMVPMatrix ); - DrawElementsWithCounters( &zeroOneSphereSurface ); + DrawElementsWithCounters( &zeroOneSphereSurface ); + } } } diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index d766e3ed..5a664c26 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -506,6 +506,7 @@ struct calcLightGridPointParms_t { // input byte* buffers[6]; // HDR RGB16F standard OpenGL cubemap sides + int area; int outWidth; int outHeight; diff --git a/neo/renderer/RenderWorld_lightgrid.cpp b/neo/renderer/RenderWorld_lightgrid.cpp index 9e92a0b1..8e2f6264 100644 --- a/neo/renderer/RenderWorld_lightgrid.cpp +++ b/neo/renderer/RenderWorld_lightgrid.cpp @@ -37,13 +37,15 @@ static const int MAX_MAP_LIGHTGRID_POINTS = 0x100000; static const int LIGHTGRID_IRRADIANCE_SIZE = 32; -void LightGrid::SetupLightGrid( const idBounds& bounds, const char* mapName ) +void LightGrid::SetupLightGrid( const idBounds& bounds, const char* mapName, const idRenderWorld* world, int area ) { //idLib::Printf( "----- SetupLightGrid -----\n" ); lightGridSize.Set( 64, 64, 128 ); lightGridPoints.Clear(); + validGridPoints = 0; + idVec3 maxs; int j = 0; int numGridPoints = MAX_MAP_LIGHTGRID_POINTS + 1; @@ -64,18 +66,22 @@ void LightGrid::SetupLightGrid( const idBounds& bounds, const char* mapName ) } } - idLib::Printf( "grid size (%i %i %i)\n", ( int )lightGridSize[0], ( int )lightGridSize[1], ( int )lightGridSize[2] ); - idLib::Printf( "grid bounds (%i %i %i)\n", ( int )lightGridBounds[0], ( int )lightGridBounds[1], ( int )lightGridBounds[2] ); + if( numGridPoints > 0 ) + { + lightGridPoints.SetNum( numGridPoints ); - idLib::Printf( "%i x %i x %i = %i grid points \n", lightGridBounds[0], lightGridBounds[1], lightGridBounds[2], numGridPoints ); + idLib::Printf( "area %i grid size (%i %i %i)\n", area, ( int )lightGridSize[0], ( int )lightGridSize[1], ( int )lightGridSize[2] ); + idLib::Printf( "area %i grid bounds (%i %i %i)\n", area, ( int )lightGridBounds[0], ( int )lightGridBounds[1], ( int )lightGridBounds[2] ); - lightGridPoints.SetNum( numGridPoints ); + idLib::Printf( "area %i (%i x %i x %i) = %i grid points \n", area, lightGridBounds[0], lightGridBounds[1], lightGridBounds[2], numGridPoints ); - idLib::Printf( "%9u x %" PRIuSIZE " = lightGridSize = (%.2fMB)\n", numGridPoints, sizeof( lightGridPoint_t ), ( float )( lightGridPoints.MemoryUsed() ) / ( 1024.0f * 1024.0f ) ); + idLib::Printf( "area %i %9u x %" PRIuSIZE " = lightGridSize = (%.2fMB)\n", area, numGridPoints, sizeof( lightGridPoint_t ), ( float )( lightGridPoints.MemoryUsed() ) / ( 1024.0f * 1024.0f ) ); - CalculateLightGridPointPositions(); + CalculateLightGridPointPositions( world, area ); + } // try to load existing lightgrid data +#if 0 idStr basename = mapName; basename.StripFileExtension(); @@ -88,6 +94,7 @@ void LightGrid::SetupLightGrid( const idBounds& bounds, const char* mapName ) fullname.Format( "env/%s/lightgridpoint%i_amb", basename.c_str(), i ); gridPoint->irradianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_R11G11B10F, CF_2D_PACKED_MIPCHAIN ); } +#endif } void LightGrid::ProbeIndexToGridIndex( const int probeIndex, int gridIndex[3] ) @@ -142,7 +149,7 @@ idVec3 LightGrid::GetProbeIndexDebugColor( const int probeIndex ) return color; } -void LightGrid::CalculateLightGridPointPositions() +void LightGrid::CalculateLightGridPointPositions( const idRenderWorld* world, int area ) { // calculate grid point positions int gridStep[3]; @@ -153,7 +160,9 @@ void LightGrid::CalculateLightGridPointPositions() gridStep[1] = lightGridBounds[0]; gridStep[2] = lightGridBounds[0] * lightGridBounds[1]; + int invalidCount = 0; int p = 0; + for( int i = 0; i < lightGridBounds[0]; i += 1 ) { for( int j = 0; j < lightGridBounds[1]; j += 1 ) @@ -172,27 +181,39 @@ void LightGrid::CalculateLightGridPointPositions() gridPoint->origin = lightGridOrigin + posFloat; + gridPoint->valid = ( world->PointInArea( gridPoint->origin ) != -1 ); + if( !gridPoint->valid ) + { + invalidCount++; + } + + gridPoint->irradianceImage = NULL; + p++; } } } + + validGridPoints = p - invalidCount; + + idLib::Printf( "area %i: %i of %i grid points in empty space (%.2f%%)\n", area, invalidCount, lightGridPoints.Num(), ( ( float ) invalidCount / lightGridPoints.Num() ) * 100 ); } void idRenderWorldLocal::SetupLightGrid() { idLib::Printf( "----- SetupLightGrid -----\n" ); - idBounds bounds; - bounds.Clear(); - + int totalGridPoints = 0; for( int i = 0; i < numPortalAreas; i++ ) { portalArea_t* area = &portalAreas[i]; - bounds.AddBounds( area->globalBounds ); + area->lightGrid.SetupLightGrid( area->globalBounds, mapName, this, i ); + + totalGridPoints += area->lightGrid.validGridPoints; } - lightGrid.SetupLightGrid( bounds, mapName ); + idLib::Printf( "total valid light grid points %i\n", totalGridPoints ); } @@ -575,7 +596,15 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL ) // CAPTURE SCENE LIGHTING TO CUBEMAPS //-------------------------------------------- - CommandlineProgressBar progressBar( tr.primaryWorld->lightGrid.lightGridPoints.Num() ); + int totalGridPoints = 0; + for( int a = 0; a < tr.primaryWorld->NumAreas(); a++ ) + { + portalArea_t* area = &tr.primaryWorld->portalAreas[a]; + + totalGridPoints += area->lightGrid.lightGridPoints.Num(); + } + + CommandlineProgressBar progressBar( totalGridPoints ); if( !useThreads ) { progressBar.Start(); @@ -583,41 +612,52 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL ) int start = Sys_Milliseconds(); - for( int i = 0; i < tr.primaryWorld->lightGrid.lightGridPoints.Num(); i++ ) + for( int a = 0; a < tr.primaryWorld->NumAreas(); a++ ) { - lightGridPoint_t* gridPoint = &tr.primaryWorld->lightGrid.lightGridPoints[i]; + portalArea_t* area = &tr.primaryWorld->portalAreas[a]; - calcLightGridPointParms_t* jobParms = new calcLightGridPointParms_t; - - for( int j = 0 ; j < 6 ; j++ ) + for( int i = 0; i < area->lightGrid.lightGridPoints.Num(); i++ ) { - ref = primary.renderView; + lightGridPoint_t* gridPoint = &area->lightGrid.lightGridPoints[i]; + if( !gridPoint->valid ) + { + progressBar.Increment(); + continue; + } - ref.rdflags = RDF_NOAMBIENT | RDF_IRRADIANCE; - ref.fov_x = ref.fov_y = 90; + calcLightGridPointParms_t* jobParms = new calcLightGridPointParms_t; + jobParms->area = a; - ref.vieworg = gridPoint->origin; - ref.viewaxis = tr.cubeAxis[j]; + for( int j = 0 ; j < 6 ; j++ ) + { + ref = primary.renderView; - extension = envDirection[ j ]; + ref.rdflags = RDF_NOAMBIENT | RDF_IRRADIANCE; + ref.fov_x = ref.fov_y = 90; - //tr.TakeScreenshot( size, size, fullname, blends, &ref, EXR ); - byte* float16FRGB = tr.CaptureRenderToBuffer( size, size, &ref ); + ref.vieworg = gridPoint->origin; + ref.viewaxis = tr.cubeAxis[j]; - jobParms->buffers[ j ] = float16FRGB; + extension = envDirection[ j ]; + + //tr.TakeScreenshot( size, size, fullname, blends, &ref, EXR ); + byte* float16FRGB = tr.CaptureRenderToBuffer( size, size, &ref ); + + jobParms->buffers[ j ] = float16FRGB; #if 0 - if( i < 3 ) - { - filename.Format( "env/%s/lightgridpoint%i%s.exr", baseName.c_str(), i, extension ); - R_WriteEXR( filename, float16FRGB, 3, size, size, "fs_basepath" ); - } + if( i < 3 ) + { + filename.Format( "env/%s/area%i_lightgridpoint%i%s.exr", baseName.c_str(), a, i, extension ); + R_WriteEXR( filename, float16FRGB, 3, size, size, "fs_basepath" ); + } #endif + } + + tr.lightGridJobs.Append( jobParms ); + + progressBar.Increment(); } - - tr.lightGridJobs.Append( jobParms ); - - progressBar.Increment(); } int end = Sys_Milliseconds(); @@ -670,7 +710,7 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL ) { calcLightGridPointParms_t* job = tr.lightGridJobs[ j ]; - filename.Format( "env/%s/lightgridpoint%i_amb.exr", baseName.c_str(), j ); + filename.Format( "env/%s/area%i_lightgridpoint%i_amb.exr", baseName.c_str(), job->area, j ); R_WriteEXR( filename.c_str(), ( byte* )job->outBuffer, 3, job->outWidth, job->outHeight, "fs_basepath" ); diff --git a/neo/renderer/RenderWorld_local.h b/neo/renderer/RenderWorld_local.h index e939f2f0..d5a51855 100644 --- a/neo/renderer/RenderWorld_local.h +++ b/neo/renderer/RenderWorld_local.h @@ -70,6 +70,8 @@ struct lightGridPoint_t // TODO REMOVE just for testing idImage* irradianceImage; + + bool valid; // is not in solid area }; class LightGrid @@ -81,11 +83,12 @@ private: public: idList lightGridPoints; + int validGridPoints; //LightGrid(); // setup light grid for given world bounds - void SetupLightGrid( const idBounds& bounds, const char* baseName ); + void SetupLightGrid( const idBounds& bounds, const char* baseName, const idRenderWorld* world, int area ); void ProbeIndexToGridIndex( const int probeIndex, int gridIndex[3] ); @@ -95,7 +98,7 @@ public: void SetupEntityGridLighting( idRenderEntityLocal* def ); private: - void CalculateLightGridPointPositions(); + void CalculateLightGridPointPositions( const idRenderWorld* world, int area ); }; // RB end @@ -107,6 +110,8 @@ typedef struct portalArea_s idBounds globalBounds; // RB: AABB of the BSP area used for light grid density + LightGrid lightGrid; + int viewCount; // set by R_FindViewLightsAndEntities portal_t* portals; // never changes after load areaReference_t entityRefs; // head/tail of doubly linked list, may change @@ -226,9 +231,6 @@ public: doublePortal_t* doublePortals; int numInterAreaPortals; - // RB: added Quake 3 style light grid - LightGrid lightGrid; - idList localModels; idList entityDefs;