Use first valid lightgrid of viewEntity areas

This commit is contained in:
Robert Beckebans 2021-04-15 21:28:50 +02:00
parent 15a9411161
commit 25b14756bb
9 changed files with 93 additions and 64 deletions

View file

@ -336,7 +336,7 @@ void main( PS_IN fragment, out PS_OUT result )
totalFactor += factor;
}
if( totalFactor > 0 && totalFactor < 0.99 )
if( totalFactor > 0.0 && totalFactor < 0.9999 )
{
totalFactor = 1.0f / totalFactor;
@ -372,7 +372,7 @@ void main( PS_IN fragment, out PS_OUT result )
float specAO = ComputeSpecularAO( vDotN, ao, roughness );
float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * specAO * ( rpSpecularModifier.xyz * 0.5 );
#if 0
#if 1
// Marmoset Horizon Fade trick
const half horizonFade = 1.3;
half horiz = saturate( 1.0 + horizonFade * saturate( dot3( reflectionVector, globalNormal ) ) );
@ -385,7 +385,7 @@ void main( PS_IN fragment, out PS_OUT result )
//result.color.rgb = diffuseLight;
//result.color.rgb = diffuseLight * lightColor;
//result.color.rgb = specularLight;
result.color.rgb = ( diffuseLight + specularLight ) * lightColor * fragment.color.rgb;
result.color.rgb = ( diffuseLight + specularLight * horiz ) * lightColor * fragment.color.rgb;
//result.color.rgb = localNormal.xyz * 0.5 + 0.5;
//result.color.rgb = float3( ao );
result.color.w = fragment.color.a;

View file

@ -1886,7 +1886,7 @@ void idRenderBackend::DBG_ShowLightGrid()
renderProgManager.BindShader_DebugLightGrid();
GL_SelectTexture( 0 );
area->lightGrid.irradianceImage->Bind();
area->lightGrid.GetIrradianceImage()->Bind();
#endif
idRenderMatrix modelRenderMatrix;

View file

@ -1323,7 +1323,7 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
const textureUsage_t specUsage = din->specularImage->GetUsage();
// RB begin
if( useIBL && viewDef->useLightGrid )
if( useIBL && currentSpace->useLightGrid )
{
idVec4 probeMins, probeMaxs, probeCenter;
@ -1347,9 +1347,9 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
//SetVertexParm( RENDERPARM_WOBBLESK_Z, probeCenter.ToFloatPtr() );
// use rpGlobalLightOrigin for lightGrid center
idVec4 lightGridOrigin( viewDef->lightGridOrigin.x, viewDef->lightGridOrigin.y, viewDef->lightGridOrigin.z, 1.0f );
idVec4 lightGridSize( viewDef->lightGridSize.x, viewDef->lightGridSize.y, viewDef->lightGridSize.z, 1.0f );
idVec4 lightGridBounds( viewDef->lightGridBounds[0], viewDef->lightGridBounds[1], viewDef->lightGridBounds[2], 1.0f );
idVec4 lightGridOrigin( currentSpace->lightGridOrigin.x, currentSpace->lightGridOrigin.y, currentSpace->lightGridOrigin.z, 1.0f );
idVec4 lightGridSize( currentSpace->lightGridSize.x, currentSpace->lightGridSize.y, currentSpace->lightGridSize.z, 1.0f );
idVec4 lightGridBounds( currentSpace->lightGridBounds[0], currentSpace->lightGridBounds[1], currentSpace->lightGridBounds[2], 1.0f );
renderProgManager.SetUniformValue( RENDERPARM_GLOBALLIGHTORIGIN, lightGridOrigin.ToFloatPtr() );
renderProgManager.SetUniformValue( RENDERPARM_JITTERTEXSCALE, lightGridSize.ToFloatPtr() );
@ -1397,14 +1397,7 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
#endif
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
if( viewDef->irradianceImage )
{
viewDef->irradianceImage->Bind();
}
else
{
globalImages->defaultUACIrradianceCube->Bind();
}
currentSpace->irradianceAtlasImage->Bind();
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE1 );
if( viewDef->radianceImage )

View file

@ -450,6 +450,15 @@ struct viewEntity_t
// be linked to the lights or added to the drawsurf list in a serial code section
drawSurf_t* drawSurfs;
// RB: use light grid of the best area this entity is in
bool useLightGrid;
idImage* irradianceAtlasImage;
idVec3 lightGridOrigin;
idVec3 lightGridSize;
int lightGridBounds[3];
// RB end
// R_AddSingleModel will build a chain of parameters here to setup shadow volumes
staticShadowVolumeParms_t* staticShadowVolumes;
dynamicShadowVolumeParms_t* dynamicShadowVolumes;
@ -636,13 +645,6 @@ struct viewDef_t
idRenderMatrix inverseBaseEnvProbeProject; // the matrix for deforming the 'zeroOneCubeModel' to exactly cover the environent probe volume in world space
idImage* irradianceImage; // cubemap image used for diffuse IBL by backend
idImage* radianceImage; // cubemap image used for specular IBL by backend
// lightGrid
bool useLightGrid;
idVec3 lightGridOrigin;
idVec3 lightGridSize;
int lightGridBounds[3];
// RB end
};

View file

@ -5573,7 +5573,7 @@ static const cgShaderDef_t cg_renderprogs[] =
" totalFactor += factor;\n"
" }\n"
"\n"
" if( totalFactor > 0 && totalFactor < 0.99 )\n"
" if( totalFactor > 0.0 && totalFactor < 0.9999 )\n"
" {\n"
" totalFactor = 1.0f / totalFactor;\n"
"\n"
@ -5609,7 +5609,7 @@ static const cgShaderDef_t cg_renderprogs[] =
" float specAO = ComputeSpecularAO( vDotN, ao, roughness );\n"
" float3 specularLight = radiance * ( kS * envBRDF.x + float3( envBRDF.y ) ) * specAO * ( rpSpecularModifier.xyz * 0.5 );\n"
"\n"
"#if 0\n"
"#if 1\n"
" // Marmoset Horizon Fade trick\n"
" const half horizonFade = 1.3;\n"
" half horiz = saturate( 1.0 + horizonFade * saturate( dot3( reflectionVector, globalNormal ) ) );\n"
@ -5622,7 +5622,7 @@ static const cgShaderDef_t cg_renderprogs[] =
" //result.color.rgb = diffuseLight;\n"
" //result.color.rgb = diffuseLight * lightColor;\n"
" //result.color.rgb = specularLight;\n"
" result.color.rgb = ( diffuseLight + specularLight ) * lightColor * fragment.color.rgb;\n"
" result.color.rgb = ( diffuseLight + specularLight * horiz ) * lightColor * fragment.color.rgb;\n"
" //result.color.rgb = localNormal.xyz * 0.5 + 0.5;\n"
" //result.color.rgb = float3( ao );\n"
" result.color.w = fragment.color.a;\n"

View file

@ -88,25 +88,25 @@ void LightGrid::SetupLightGrid( const idBounds& bounds, const char* mapName, con
idLib::Printf( "area %i %9u x %" PRIuSIZE " = lightGridSize = (%.2fMB)\n", area, numGridPoints, sizeof( lightGridPoint_t ), ( float )( lightGridPoints.MemoryUsed() ) / ( 1024.0f * 1024.0f ) );
CalculateLightGridPointPositions( world, area );
}
// try to load existing lightgrid data
// try to load existing lightgrid data
#if 1
idStr basename = mapName;
basename.StripFileExtension();
idStr basename = mapName;
basename.StripFileExtension();
idStr fullname;
idStr fullname;
fullname.Format( "env/%s/area%i_lightgrid_amb", basename.c_str(), area );
irradianceImage = globalImages->ImageFromFile( fullname, TF_NEAREST, TR_CLAMP, TD_R11G11B10F, CF_2D );
fullname.Format( "env/%s/area%i_lightgrid_amb", basename.c_str(), area );
irradianceImage = globalImages->ImageFromFile( fullname, TF_NEAREST, TR_CLAMP, TD_R11G11B10F, CF_2D );
#else
for( int i = 0; i < lightGridPoints.Num(); i++ )
{
lightGridPoint_t* gridPoint = &lightGridPoints[i];
for( int i = 0; i < lightGridPoints.Num(); i++ )
{
lightGridPoint_t* gridPoint = &lightGridPoints[i];
gridPoint->irradianceImage = NULL;
}
gridPoint->irradianceImage = NULL;
}
#endif
}
}
void LightGrid::GetBaseGridCoord( const idVec3& origin, int gridCoord[3] )
@ -634,6 +634,12 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL )
static const char* envDirection[6] = { "_px", "_nx", "_py", "_ny", "_pz", "_nz" };
if( args.Argc() != 1 && args.Argc() != 2 )
{
common->Printf( "USAGE: generateLightData [limit] (limit is max probes per BSP area)\n" );
return;
}
if( !tr.primaryWorld )
{
common->Printf( "No primary world loaded.\n" );
@ -654,6 +660,14 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL )
return;
}
int limit = MAX_AREA_LIGHTGRID_POINTS;
if( args.Argc() >= 2 )
{
limit = atoi( args.Argv( 1 ) );
}
idLib::Printf( "Using limit = %i\n", limit );
const viewDef_t primary = *tr.primaryView;
//--------------------------------------------
@ -670,7 +684,7 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL )
}
*/
#if 1
#if 0
int a = tr.primaryWorld->PointInArea( tr.primaryView->renderView.vieworg );
if( a == -1 )
{
@ -682,9 +696,15 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL )
{
portalArea_t* area = &tr.primaryWorld->portalAreas[a];
idLib::Printf( "Shooting %i grid probes area %i...\n\n", area->lightGrid.lightGridPoints.Num(), a );
int numGridPoints = Min( area->lightGrid.lightGridPoints.Num(), limit );
if( numGridPoints == 0 )
{
continue;
}
CommandlineProgressBar progressBar( area->lightGrid.lightGridPoints.Num() );
idLib::Printf( "Shooting %i grid probes area %i...\n", numGridPoints, a );
CommandlineProgressBar progressBar( numGridPoints );
if( !useThreads )
{
progressBar.Start();
@ -711,7 +731,7 @@ CONSOLE_COMMAND( generateLightGrid, "Generate light grid data", NULL )
gridCoord[2] = k;
lightGridPoint_t* gridPoint = &area->lightGrid.lightGridPoints[ gridCoord[0] * gridStep[0] + gridCoord[1] * gridStep[1] + gridCoord[2] * gridStep[2] ];
if( !gridPoint->valid )
if( !gridPoint->valid || ( tr.lightGridJobs.Num() >= limit ) )
{
progressBar.Increment();
continue;

View file

@ -71,6 +71,9 @@ struct lightGridPoint_t
class LightGrid
{
private:
idImage* irradianceImage;
public:
idVec3 lightGridOrigin;
idVec3 lightGridSize;
@ -81,8 +84,6 @@ public:
idList<lightGridPoint_t> lightGridPoints;
int validGridPoints;
idImage* irradianceImage;
LightGrid();
// setup light grid for given world bounds
@ -96,6 +97,11 @@ public:
idVec3 GetGridCoordDebugColor( int gridCoord[3] );
idVec3 GetProbeIndexDebugColor( const int probeIndex );
idImage* GetIrradianceImage() const
{
return irradianceImage;
}
// fetch grid lighting on a per object basis
void SetupEntityGridLighting( idRenderEntityLocal* def );

View file

@ -373,6 +373,9 @@ void R_AddSingleModel( viewEntity_t* vEntity )
vEntity->staticShadowVolumes = NULL;
vEntity->dynamicShadowVolumes = NULL;
// RB
vEntity->useLightGrid = false;
// globals we really should pass in...
const viewDef_t* viewDef = tr.viewDef;
@ -549,6 +552,30 @@ void R_AddSingleModel( viewEntity_t* vEntity )
}
}
// RB: use first valid lightgrid
for( areaReference_t* ref = entityDef->entityRefs; ref != NULL; ref = ref->ownerNext )
{
idImage* lightGridImage = ref->area->lightGrid.GetIrradianceImage();
if( ref->area->lightGrid.lightGridPoints.Num() && lightGridImage && !lightGridImage->IsDefaulted() )
{
vEntity->useLightGrid = true;
vEntity->irradianceAtlasImage = lightGridImage;
for( int i = 0; i < 3; i++ )
{
vEntity->lightGridOrigin[i] = ref->area->lightGrid.lightGridOrigin[i];
vEntity->lightGridSize[i] = ref->area->lightGrid.lightGridSize[i];
vEntity->lightGridBounds[i] = ref->area->lightGrid.lightGridBounds[i];
}
break;
}
}
// RB end
//---------------------------
// copy matrix related stuff for back-end use
// and setup a render matrix for faster culling

View file

@ -549,22 +549,6 @@ void R_RenderView( viewDef_t* parms )
tr.viewDef->irradianceImage = globalImages->defaultUACIrradianceCube;
tr.viewDef->radianceImage = globalImages->defaultUACRadianceCube;
bool useLightGrid = tr.viewDef->useLightGrid = false;
portalArea_t* area = &tr.primaryWorld->portalAreas[tr.viewDef->areaNum];
if( area->lightGrid.irradianceImage && !area->lightGrid.irradianceImage->IsDefaulted() )
{
tr.viewDef->irradianceImage = area->lightGrid.irradianceImage;
tr.viewDef->useLightGrid = useLightGrid = true;
for( int i = 0; i < 3; i++ )
{
tr.viewDef->lightGridOrigin[i] = area->lightGrid.lightGridOrigin[i];
tr.viewDef->lightGridSize[i] = area->lightGrid.lightGridSize[i];
tr.viewDef->lightGridBounds[i] = area->lightGrid.lightGridBounds[i];
}
}
for( viewEnvprobe_t* vProbe = tr.viewDef->viewEnvprobes; vProbe != NULL; vProbe = vProbe->next )
{
float dist = ( tr.viewDef->renderView.vieworg - vProbe->globalOrigin ).Length();
@ -574,10 +558,7 @@ void R_RenderView( viewDef_t* parms )
{
tr.viewDef->globalProbeBounds = vProbe->globalProbeBounds;
if( !useLightGrid )
{
tr.viewDef->irradianceImage = vProbe->irradianceImage;
}
tr.viewDef->irradianceImage = vProbe->irradianceImage;
tr.viewDef->radianceImage = vProbe->radianceImage;
bestDist = dist;