From 25b14756bb297e93ff1fd163a3c42ab25372016f Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Thu, 15 Apr 2021 21:28:50 +0200 Subject: [PATCH] Use first valid lightgrid of viewEntity areas --- .../lighting/ambient_lightgrid_IBL.ps.hlsl | 6 +-- neo/renderer/OpenGL/RenderDebug_GL.cpp | 2 +- neo/renderer/RenderBackend.cpp | 17 ++---- neo/renderer/RenderCommon.h | 16 +++--- neo/renderer/RenderProgs_embedded.h | 6 +-- neo/renderer/RenderWorld_lightgrid.cpp | 52 +++++++++++++------ neo/renderer/RenderWorld_local.h | 10 +++- neo/renderer/tr_frontend_addmodels.cpp | 27 ++++++++++ neo/renderer/tr_frontend_main.cpp | 21 +------- 9 files changed, 93 insertions(+), 64 deletions(-) diff --git a/base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.ps.hlsl b/base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.ps.hlsl index c459e1a1..91d4622e 100644 --- a/base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.ps.hlsl +++ b/base/renderprogs/builtin/lighting/ambient_lightgrid_IBL.ps.hlsl @@ -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; diff --git a/neo/renderer/OpenGL/RenderDebug_GL.cpp b/neo/renderer/OpenGL/RenderDebug_GL.cpp index 5bed7dc6..37ee6bc0 100644 --- a/neo/renderer/OpenGL/RenderDebug_GL.cpp +++ b/neo/renderer/OpenGL/RenderDebug_GL.cpp @@ -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; diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 4c3d424d..35251fc2 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -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 ) diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index 17910cbe..648d9f5e 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -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 }; diff --git a/neo/renderer/RenderProgs_embedded.h b/neo/renderer/RenderProgs_embedded.h index 0cd0f58e..2fc4b16a 100644 --- a/neo/renderer/RenderProgs_embedded.h +++ b/neo/renderer/RenderProgs_embedded.h @@ -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" diff --git a/neo/renderer/RenderWorld_lightgrid.cpp b/neo/renderer/RenderWorld_lightgrid.cpp index bb6ef4d2..df9c303c 100644 --- a/neo/renderer/RenderWorld_lightgrid.cpp +++ b/neo/renderer/RenderWorld_lightgrid.cpp @@ -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; diff --git a/neo/renderer/RenderWorld_local.h b/neo/renderer/RenderWorld_local.h index 11bb9e13..2ab9038e 100644 --- a/neo/renderer/RenderWorld_local.h +++ b/neo/renderer/RenderWorld_local.h @@ -71,6 +71,9 @@ struct lightGridPoint_t class LightGrid { +private: + idImage* irradianceImage; + public: idVec3 lightGridOrigin; idVec3 lightGridSize; @@ -81,8 +84,6 @@ public: idList 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 ); diff --git a/neo/renderer/tr_frontend_addmodels.cpp b/neo/renderer/tr_frontend_addmodels.cpp index 3d09e054..7affc283 100644 --- a/neo/renderer/tr_frontend_addmodels.cpp +++ b/neo/renderer/tr_frontend_addmodels.cpp @@ -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 diff --git a/neo/renderer/tr_frontend_main.cpp b/neo/renderer/tr_frontend_main.cpp index 5adfb5f3..54d17e19 100644 --- a/neo/renderer/tr_frontend_main.cpp +++ b/neo/renderer/tr_frontend_main.cpp @@ -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;