mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 06:34:10 +00:00
All lights can be culled now
This commit is contained in:
parent
e121472661
commit
a7d1d7f72e
5 changed files with 113 additions and 95 deletions
|
@ -3,7 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2014 Robert Beckebans
|
||||
Copyright (C) 2014-2024 Robert Beckebans
|
||||
Copyright (C) 2022 Stephen Pridham
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
|
|
@ -1975,40 +1975,6 @@ static void R_MakeZeroOneCubeTrisForMaskedOcclusionCulling()
|
|||
verts[5].w = 1;
|
||||
verts[6].w = 1;
|
||||
verts[7].w = 1;
|
||||
}
|
||||
|
||||
static void R_MakeUnitCubeTrisForMaskedOcclusionCulling()
|
||||
{
|
||||
const float low = -1.0f;
|
||||
const float high = 1.0f;
|
||||
|
||||
idVec3 center( 0.0f );
|
||||
idVec3 mx( low, 0.0f, 0.0f );
|
||||
idVec3 px( high, 0.0f, 0.0f );
|
||||
idVec3 my( 0.0f, low, 0.0f );
|
||||
idVec3 py( 0.0f, high, 0.0f );
|
||||
idVec3 mz( 0.0f, 0.0f, low );
|
||||
idVec3 pz( 0.0f, 0.0f, high );
|
||||
|
||||
idVec4* verts = tr.maskedUnitCubeVerts;
|
||||
|
||||
verts[0].ToVec3() = center + mx + my + mz;
|
||||
verts[1].ToVec3() = center + px + my + mz;
|
||||
verts[2].ToVec3() = center + px + py + mz;
|
||||
verts[3].ToVec3() = center + mx + py + mz;
|
||||
verts[4].ToVec3() = center + mx + my + pz;
|
||||
verts[5].ToVec3() = center + px + my + pz;
|
||||
verts[6].ToVec3() = center + px + py + pz;
|
||||
verts[7].ToVec3() = center + mx + py + pz;
|
||||
|
||||
verts[0].w = 1;
|
||||
verts[1].w = 1;
|
||||
verts[2].w = 1;
|
||||
verts[3].w = 1;
|
||||
verts[4].w = 1;
|
||||
verts[5].w = 1;
|
||||
verts[6].w = 1;
|
||||
verts[7].w = 1;
|
||||
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
|
||||
|
@ -2056,6 +2022,40 @@ static void R_MakeUnitCubeTrisForMaskedOcclusionCulling()
|
|||
indexes[11 * 3 + 2] = 6;
|
||||
}
|
||||
|
||||
static void R_MakeUnitCubeTrisForMaskedOcclusionCulling()
|
||||
{
|
||||
const float low = -1.0f;
|
||||
const float high = 1.0f;
|
||||
|
||||
idVec3 center( 0.0f );
|
||||
idVec3 mx( low, 0.0f, 0.0f );
|
||||
idVec3 px( high, 0.0f, 0.0f );
|
||||
idVec3 my( 0.0f, low, 0.0f );
|
||||
idVec3 py( 0.0f, high, 0.0f );
|
||||
idVec3 mz( 0.0f, 0.0f, low );
|
||||
idVec3 pz( 0.0f, 0.0f, high );
|
||||
|
||||
idVec4* verts = tr.maskedUnitCubeVerts;
|
||||
|
||||
verts[0].ToVec3() = center + mx + my + mz;
|
||||
verts[1].ToVec3() = center + px + my + mz;
|
||||
verts[2].ToVec3() = center + px + py + mz;
|
||||
verts[3].ToVec3() = center + mx + py + mz;
|
||||
verts[4].ToVec3() = center + mx + my + pz;
|
||||
verts[5].ToVec3() = center + px + my + pz;
|
||||
verts[6].ToVec3() = center + px + py + pz;
|
||||
verts[7].ToVec3() = center + mx + py + pz;
|
||||
|
||||
verts[0].w = 1;
|
||||
verts[1].w = 1;
|
||||
verts[2].w = 1;
|
||||
verts[3].w = 1;
|
||||
verts[4].w = 1;
|
||||
verts[5].w = 1;
|
||||
verts[6].w = 1;
|
||||
verts[7].w = 1;
|
||||
}
|
||||
|
||||
static srfTriangles_t* R_MakeZeroOneSphereTris()
|
||||
{
|
||||
srfTriangles_t* tri = ( srfTriangles_t* )Mem_ClearedAlloc( sizeof( *tri ), TAG_RENDER_TOOLS );
|
||||
|
|
|
@ -371,7 +371,7 @@ void idRenderWorldLocal::AddAreaViewLights( int areaNum, const portalStack_t* ps
|
|||
|
||||
// debug tool to allow viewing of only one light at a time
|
||||
// RB: use this elsewhere in the backend debug drawing code
|
||||
#if 0
|
||||
#if 1
|
||||
if( r_singleLight.GetInteger() >= 0 && r_singleLight.GetInteger() != light->index )
|
||||
{
|
||||
continue;
|
||||
|
|
|
@ -271,10 +271,9 @@ static void R_AddSingleLight( viewLight_t* vLight )
|
|||
// RB: test surface visibility by drawing the triangles of the bounds
|
||||
|
||||
// FIXME spot light projections are too short
|
||||
if( r_useMaskedOcclusionCulling.GetBool() && !viewInsideLight && vLight->pointLight )
|
||||
if( r_useMaskedOcclusionCulling.GetBool() && !viewInsideLight )
|
||||
{
|
||||
#if 1
|
||||
idVec4 triVerts[3];
|
||||
idVec4 triVerts[8];
|
||||
unsigned int triIndices[] = { 0, 1, 2 };
|
||||
|
||||
tr.pc.c_mocIndexes += 36;
|
||||
|
@ -285,64 +284,81 @@ static void R_AddSingleLight( viewLight_t* vLight )
|
|||
|
||||
tr.pc.c_mocTests += 1;
|
||||
|
||||
float wmin = idMath::INFINITUM;
|
||||
bool maskVisible = false;
|
||||
|
||||
// NOTE: zeroToOne cube is only for lights and models need the unit cube
|
||||
idVec4* verts = tr.maskedZeroOneCubeVerts;
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
for( int i = 0, face = 0; i < 36; i += 3, face++ )
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
const idVec4& v0 = verts[indexes[i + 0]];
|
||||
const idVec4& v1 = verts[indexes[i + 1]];
|
||||
const idVec4& v2 = verts[indexes[i + 2]];
|
||||
|
||||
// transform to clip space
|
||||
invProjectMVPMatrix.TransformPoint( v0, triVerts[0] );
|
||||
invProjectMVPMatrix.TransformPoint( v1, triVerts[1] );
|
||||
invProjectMVPMatrix.TransformPoint( v2, triVerts[2] );
|
||||
invProjectMVPMatrix.TransformPoint( verts[i], triVerts[i] );
|
||||
|
||||
float w = triVerts[i].w;
|
||||
if( i == 0 )
|
||||
{
|
||||
wmin = w;
|
||||
}
|
||||
else if( w < wmin )
|
||||
{
|
||||
wmin = w;
|
||||
}
|
||||
}
|
||||
|
||||
if( vLight->pointLight || vLight->parallel )
|
||||
{
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
for( int i = 0; i < 36; i += 3 )
|
||||
{
|
||||
triIndices[0] = indexes[i + 0];
|
||||
triIndices[1] = indexes[i + 1];
|
||||
triIndices[2] = indexes[i + 2];
|
||||
|
||||
#if 1
|
||||
// backface none so objects are still visible where we run into
|
||||
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
|
||||
if( result == MaskedOcclusionCulling::VISIBLE )
|
||||
{
|
||||
// backface none so objects are still visible where we run into
|
||||
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
|
||||
if( result == MaskedOcclusionCulling::VISIBLE )
|
||||
{
|
||||
maskVisible = true;
|
||||
}
|
||||
#else
|
||||
// draw for debugging
|
||||
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CW );
|
||||
maskVisible = true;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
// draw for debugging
|
||||
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
|
||||
maskVisible = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
if( !maskVisible )
|
||||
if( !maskVisible )
|
||||
{
|
||||
tr.pc.c_mocCulledLights += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_mocCulledLights += 1;
|
||||
return;
|
||||
// scissor test alternative
|
||||
|
||||
// source scissor rectangle has GL convention and starts in the lower left corner
|
||||
// convert to NDC values
|
||||
float x1 = -1.0f + ( float( vLight->scissorRect.x1 ) / screenWidth ) * 2.0f;
|
||||
float x2 = -1.0f + ( float( vLight->scissorRect.x2 ) / screenWidth ) * 2.0f;
|
||||
float y1 = -1.0f + ( float( vLight->scissorRect.y1 ) / screenHeight ) * 2.0f;
|
||||
float y2 = -1.0f + ( float( vLight->scissorRect.y2 ) / screenHeight ) * 2.0f;
|
||||
|
||||
float zmin = vLight->scissorRect.zmin;
|
||||
//zmin = 2.0f * zmin -1.0f;
|
||||
zmin = 1.0 - zmin; // reverse depth
|
||||
float wmin2 = ( 1.0 / zmin );
|
||||
wmin2 *= wmin;
|
||||
wmin2 = Max( wmin2, 0.0f );
|
||||
|
||||
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestRect( x1, y1, x2, y2, wmin2 );
|
||||
if( result != MaskedOcclusionCulling::VISIBLE )
|
||||
{
|
||||
tr.pc.c_mocCulledLights += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// scissor test alternative
|
||||
// I would prefer this method however lights become visible again when the distance increases to the occluder surface
|
||||
|
||||
// source scissor rectangle has GL convention and starts in the lower left corner
|
||||
// convert to NDC values
|
||||
float x1 = -1.0f + ( float( vLight->scissorRect.x1 ) / screenWidth ) * 2.0f;
|
||||
float x2 = -1.0f + ( float( vLight->scissorRect.x2 ) / screenWidth ) * 2.0f;
|
||||
float y1 = -1.0f + ( float( vLight->scissorRect.y1 ) / screenHeight ) * 2.0f;
|
||||
float y2 = -1.0f + ( float( vLight->scissorRect.y2 ) / screenHeight ) * 2.0f;
|
||||
|
||||
//float y2 = -1.0f + ( float( screenHeight - vLight->scissorRect.y1 ) / screenHeight ) * 2.0f;
|
||||
//float y1 = -1.0f + ( float( screenHeight - vLight->scissorRect.y2 ) / screenHeight ) * 2.0f;
|
||||
|
||||
double zmin = 1.0 - vLight->scissorRect.zmin; // reverse depth
|
||||
double wmin = 1.0 / zmin;
|
||||
|
||||
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestRect( x1, y1, x2, y2, wmin );
|
||||
if( result != MaskedOcclusionCulling::VISIBLE )
|
||||
{
|
||||
tr.pc.c_mocCulledLights += 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// RB end
|
||||
|
||||
|
|
|
@ -686,7 +686,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
|
|||
#if 1
|
||||
if( !model->IsStaticWorldModel() && !renderEntity->weaponDepthHack && renderEntity->modelDepthHack == 0.0f )
|
||||
{
|
||||
idVec4 triVerts[3];
|
||||
idVec4 triVerts[8];
|
||||
unsigned int triIndices[] = { 0, 1, 2 };
|
||||
|
||||
tr.pc.c_mocIndexes += 36;
|
||||
|
@ -719,19 +719,21 @@ void R_AddSingleModel( viewEntity_t* vEntity )
|
|||
tr.pc.c_mocTests += 1;
|
||||
|
||||
bool maskVisible = false;
|
||||
|
||||
// NOTE: unit cube instead of zeroToOne cube
|
||||
idVec4* verts = tr.maskedUnitCubeVerts;
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
for( int i = 0, face = 0; i < 36; i += 3, face++ )
|
||||
for( int i = 0; i < 8; i++ )
|
||||
{
|
||||
const idVec4& v0 = verts[indexes[i + 0]];
|
||||
const idVec4& v1 = verts[indexes[i + 1]];
|
||||
const idVec4& v2 = verts[indexes[i + 2]];
|
||||
|
||||
// transform to clip space
|
||||
invProjectMVPMatrix.TransformPoint( v0, triVerts[0] );
|
||||
invProjectMVPMatrix.TransformPoint( v1, triVerts[1] );
|
||||
invProjectMVPMatrix.TransformPoint( v2, triVerts[2] );
|
||||
invProjectMVPMatrix.TransformPoint( verts[i], triVerts[i] );
|
||||
}
|
||||
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
for( int i = 0; i < 36; i += 3 )
|
||||
{
|
||||
triIndices[0] = indexes[i + 0];
|
||||
triIndices[1] = indexes[i + 1];
|
||||
triIndices[2] = indexes[i + 2];
|
||||
|
||||
// backface none so objects are still visible where we run into
|
||||
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
|
||||
|
|
Loading…
Reference in a new issue