mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-13 22:22:05 +00:00
Fixed bad lightgrid lookups if models span multiple areas. close #965
This commit is contained in:
parent
67987ab715
commit
56648e631f
7 changed files with 112 additions and 61 deletions
|
@ -447,7 +447,7 @@ textures/common/occlusion
|
|||
// so it works as a blocker for the lightgrid
|
||||
textures/common/black
|
||||
{
|
||||
qer_editorimage textures/common/shadow.tga
|
||||
qer_editorimage textures/common/black.tga
|
||||
nonsolid
|
||||
forceshadows
|
||||
forceOpaque
|
||||
|
|
BIN
base/textures/common/black.png
Normal file
BIN
base/textures/common/black.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
|
@ -4173,7 +4173,7 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f
|
|||
|
||||
if( testStamp != FILE_NOT_FOUND_TIMESTAMP )
|
||||
{
|
||||
if( name.Cmp( "_normal_opengl" ) == 0 )
|
||||
if( name.Cmp( "_normal_opengl" ) == 0 || ueMode )
|
||||
{
|
||||
mtrBuffer += va( "\tnormalmap invertGreen( %s )\n", testName.c_str() );
|
||||
}
|
||||
|
|
|
@ -1177,7 +1177,7 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
const textureUsage_t specUsage = din->specularImage->GetUsage();
|
||||
|
||||
// RB begin
|
||||
if( useIBL && currentSpace->useLightGrid && r_useLightGrid.GetBool() )
|
||||
if( useIBL && din->surf->area != NULL && r_useLightGrid.GetBool() )
|
||||
{
|
||||
idVec4 probeMins, probeMaxs, probeCenter;
|
||||
|
||||
|
@ -1199,9 +1199,11 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
SetVertexParm( RENDERPARM_WOBBLESKY_Z, probeCenter.ToFloatPtr() );
|
||||
|
||||
// use rpGlobalLightOrigin for lightGrid center
|
||||
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 );
|
||||
const LightGrid& lightGrid = din->surf->area->lightGrid;
|
||||
|
||||
idVec4 lightGridOrigin( lightGrid.lightGridOrigin.x, lightGrid.lightGridOrigin.y, lightGrid.lightGridOrigin.z, 1.0f );
|
||||
idVec4 lightGridSize( lightGrid.lightGridSize.x, lightGrid.lightGridSize.y, lightGrid.lightGridSize.z, 1.0f );
|
||||
idVec4 lightGridBounds( lightGrid.lightGridBounds[0], lightGrid.lightGridBounds[1], lightGrid.lightGridBounds[2], 1.0f );
|
||||
|
||||
renderProgManager.SetUniformValue( RENDERPARM_GLOBALLIGHTORIGIN, lightGridOrigin.ToFloatPtr() );
|
||||
renderProgManager.SetUniformValue( RENDERPARM_JITTERTEXSCALE, lightGridSize.ToFloatPtr() );
|
||||
|
@ -1209,10 +1211,10 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
|
||||
// individual probe sizes on the atlas image
|
||||
idVec4 probeSize;
|
||||
probeSize[0] = currentSpace->lightGridAtlasSingleProbeSize - currentSpace->lightGridAtlasBorderSize;
|
||||
probeSize[1] = currentSpace->lightGridAtlasSingleProbeSize;
|
||||
probeSize[2] = currentSpace->lightGridAtlasBorderSize;
|
||||
probeSize[3] = float( currentSpace->lightGridAtlasSingleProbeSize - currentSpace->lightGridAtlasBorderSize ) / currentSpace->lightGridAtlasSingleProbeSize;
|
||||
probeSize[0] = lightGrid.imageSingleProbeSize - lightGrid.imageBorderSize;
|
||||
probeSize[1] = lightGrid.imageSingleProbeSize;
|
||||
probeSize[2] = lightGrid.imageBorderSize;
|
||||
probeSize[3] = float( lightGrid.imageSingleProbeSize - lightGrid.imageBorderSize ) / lightGrid.imageSingleProbeSize;
|
||||
renderProgManager.SetUniformValue( RENDERPARM_SCREENCORRECTIONFACTOR, probeSize.ToFloatPtr() ); // rpScreenCorrectionFactor
|
||||
|
||||
// specular cubemap blend weights
|
||||
|
@ -1256,9 +1258,9 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useFas
|
|||
}
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
|
||||
currentSpace->lightGridAtlasImage->Bind();
|
||||
lightGrid.GetIrradianceImage()->Bind();
|
||||
|
||||
idVec2i res = currentSpace->lightGridAtlasImage->GetUploadResolution();
|
||||
idVec2i res = lightGrid.GetIrradianceImage()->GetUploadResolution();
|
||||
idVec4 textureSize( res.x, res.y, 1.0f / res.x, 1.0f / res.y );
|
||||
|
||||
renderProgManager.SetUniformValue( RENDERPARM_CASCADEDISTANCES, textureSize.ToFloatPtr() );
|
||||
|
|
|
@ -98,10 +98,11 @@ struct drawSurf_t
|
|||
const idMaterial* material; // may be NULL for shadow volumes
|
||||
uint64 extraGLState; // Extra GL state |'d with material->stage[].drawStateBits
|
||||
float sort; // material->sort, modified by gui / entity sort offsets
|
||||
const float* shaderRegisters; // evaluated and adjusted for referenceShaders
|
||||
const float* shaderRegisters; // evaluated and adjusted for referenceShaders
|
||||
drawSurf_t* nextOnLight; // viewLight chains
|
||||
drawSurf_t** linkChain; // defer linking to lights to a serial section to avoid a mutex
|
||||
idScreenRect scissorRect; // for scissor clipping, local inside renderView viewport
|
||||
const struct portalArea_s* area; // RB: if != NULL then the area provides valid lightgrid
|
||||
};
|
||||
|
||||
// areas have references to hold all the lights and entities in them
|
||||
|
@ -422,17 +423,6 @@ struct viewEntity_t
|
|||
// parallelAddModels will build a chain of surfaces here that will need to
|
||||
// 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* lightGridAtlasImage;
|
||||
int lightGridAtlasSingleProbeSize; // including border
|
||||
int lightGridAtlasBorderSize;
|
||||
|
||||
idVec3 lightGridOrigin;
|
||||
idVec3 lightGridSize;
|
||||
int lightGridBounds[3];
|
||||
// RB end
|
||||
};
|
||||
|
||||
// RB: viewEnvprobes are allocated on the frame temporary stack memory
|
||||
|
|
|
@ -315,9 +315,6 @@ void R_AddSingleModel( viewEntity_t* vEntity )
|
|||
// we will add all interaction surfs here, to be chained to the lights in later serial code
|
||||
vEntity->drawSurfs = NULL;
|
||||
|
||||
// RB
|
||||
vEntity->useLightGrid = false;
|
||||
|
||||
// globals we really should pass in...
|
||||
const viewDef_t* viewDef = tr.viewDef;
|
||||
|
||||
|
@ -494,32 +491,6 @@ 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->lightGridAtlasImage = lightGridImage;
|
||||
vEntity->lightGridAtlasSingleProbeSize = ref->area->lightGrid.imageSingleProbeSize;
|
||||
vEntity->lightGridAtlasBorderSize = ref->area->lightGrid.imageBorderSize;
|
||||
|
||||
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
|
||||
|
@ -756,8 +727,6 @@ void R_AddSingleModel( viewEntity_t* vEntity )
|
|||
}
|
||||
#endif // #if defined(USE_INTRINSICS_SSE)
|
||||
|
||||
|
||||
|
||||
//--------------------------
|
||||
// base drawing surface
|
||||
//--------------------------
|
||||
|
@ -841,6 +810,99 @@ void R_AddSingleModel( viewEntity_t* vEntity )
|
|||
baseDrawSurf->nextOnLight = vEntity->drawSurfs;
|
||||
vEntity->drawSurfs = baseDrawSurf;
|
||||
}
|
||||
|
||||
// RB: use area the surface is in because a model can span multiple areas #965
|
||||
baseDrawSurf->area = NULL;
|
||||
|
||||
if( shader->ReceivesLighting() )
|
||||
{
|
||||
idVec3 surfaceCenter;
|
||||
idVec3 triCenter = tri->bounds.GetCenter();
|
||||
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::CreateFromOriginAxis( renderEntity->origin, renderEntity->axis, modelRenderMatrix );
|
||||
modelRenderMatrix.TransformPoint( triCenter, surfaceCenter );
|
||||
|
||||
int surfaceArea = tr.primaryWorld->PointInArea( surfaceCenter );
|
||||
|
||||
for( areaReference_t* ref = entityDef->entityRefs; ref != NULL; ref = ref->ownerNext )
|
||||
{
|
||||
idImage* lightGridImage = ref->area->lightGrid.GetIrradianceImage();
|
||||
|
||||
if( surfaceArea == ref->area->areaNum && ref->area->lightGrid.lightGridPoints.Num() && lightGridImage != NULL && !lightGridImage->IsDefaulted() )
|
||||
{
|
||||
baseDrawSurf->area = ref->area;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// RB: use first valid lightgrid
|
||||
// this would be wrong but less wrong than a flickering env_probe fallback
|
||||
if( baseDrawSurf->area == NULL )
|
||||
{
|
||||
for( areaReference_t* ref = entityDef->entityRefs; ref != NULL; ref = ref->ownerNext )
|
||||
{
|
||||
idImage* lightGridImage = ref->area->lightGrid.GetIrradianceImage();
|
||||
|
||||
if( ref->area->lightGrid.lightGridPoints.Num() && lightGridImage != NULL && !lightGridImage->IsDefaulted() )
|
||||
{
|
||||
baseDrawSurf->area = ref->area;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// show which area the surface is coming from
|
||||
//if( baseDrawSurf->area == NULL )
|
||||
{
|
||||
idBounds surfaceBounds;
|
||||
if( gpuSkinned )
|
||||
{
|
||||
surfaceBounds = vEntity->entityDef->localReferenceBounds;
|
||||
}
|
||||
else
|
||||
{
|
||||
surfaceBounds = tri->bounds;
|
||||
}
|
||||
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::CreateFromOriginAxis( renderEntity->origin, renderEntity->axis, modelRenderMatrix );
|
||||
|
||||
idRenderMatrix inverseBaseModelProject;
|
||||
idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, surfaceBounds, inverseBaseModelProject );
|
||||
|
||||
// NOTE: unit cube instead of zeroToOne cube
|
||||
idVec4* verts = tr.maskedUnitCubeVerts;
|
||||
idVec4 triVerts[8];
|
||||
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
// transform to clip space
|
||||
inverseBaseModelProject.TransformPoint( verts[i], triVerts[i] );
|
||||
}
|
||||
|
||||
static idVec4 colors[] = { colorBrown, colorBlue, colorCyan, colorGreen, colorYellow, colorRed, colorWhite };
|
||||
idVec4 color = colors[surfaceArea & 7];
|
||||
|
||||
if( baseDrawSurf->area == NULL )
|
||||
{
|
||||
color = colorPurple;
|
||||
}
|
||||
|
||||
// same as idRenderWorldLocal::DebugBox
|
||||
const int lifetime = 0;
|
||||
for( int i = 0; i < 4; i++ )
|
||||
{
|
||||
tr.viewDef->renderWorld->DebugLine( color, triVerts[i].ToVec3(), triVerts[( i + 1 ) & 3].ToVec3(), lifetime );
|
||||
tr.viewDef->renderWorld->DebugLine( color, triVerts[4 + i].ToVec3(), triVerts[4 + ( ( i + 1 ) & 3 )].ToVec3(), lifetime );
|
||||
tr.viewDef->renderWorld->DebugLine( color, triVerts[i].ToVec3(), triVerts[4 + i].ToVec3(), lifetime );
|
||||
}
|
||||
|
||||
tr.viewDef->renderWorld->DebugAxis( surfaceCenter, renderEntity->axis );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
|
|
@ -242,14 +242,11 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
gridCoord[j] = int( floor( v ) );
|
||||
frac[ j ] = v - gridCoord[ j ];
|
||||
|
||||
/*
|
||||
if( gridCoord[i] < 0 )
|
||||
if( gridCoord[j] < 0 )
|
||||
{
|
||||
gridCoord[i] = 0;
|
||||
gridCoord[j] = 0;
|
||||
}
|
||||
else
|
||||
*/
|
||||
if( gridCoord[j] >= lightGridBounds[j] - 1 )
|
||||
else if( gridCoord[j] >= lightGridBounds[j] - 1 )
|
||||
{
|
||||
gridCoord[j] = lightGridBounds[j] - 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue