Splitted light grid up into multiple for each BSP area

This commit is contained in:
Robert Beckebans 2021-04-13 19:53:02 +02:00
parent 99c7d58dc6
commit f1e54f249b
4 changed files with 158 additions and 98 deletions

View file

@ -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 );
}
}
}

View file

@ -506,6 +506,7 @@ struct calcLightGridPointParms_t
{
// input
byte* buffers[6]; // HDR RGB16F standard OpenGL cubemap sides
int area;
int outWidth;
int outHeight;

View file

@ -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" );

View file

@ -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<lightGridPoint_t> 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<idRenderModel*, TAG_MODEL> localModels;
idList<idRenderEntityLocal*, TAG_ENTITY> entityDefs;