Only draw BSP surfs/patches to masked buffer to reduce tris

This commit is contained in:
Robert Beckebans 2024-09-02 23:14:08 +02:00
parent 1e2b1be338
commit 6c00d6bcdd
6 changed files with 25 additions and 104 deletions

View file

@ -13,6 +13,9 @@
// License for the specific language governing permissions and limitations
// under the License.
////////////////////////////////////////////////////////////////////////////////
#include "precompiled.h"
#pragma hdrstop
#include <assert.h>
#include "CullingThreadpool.h"
@ -366,7 +369,7 @@ CullingThreadpool::~CullingThreadpool()
// Wait for threads to terminate
if( mThreads != nullptr || !mKillThreads )
{
WakeThreads();
//WakeThreads();
mKillThreads = true;
for( unsigned int i = 0; i < mNumThreads; ++i )
{

View file

@ -65,7 +65,7 @@ SURFACES
#include "Interaction.h"
// RB begin
#define MOC_MULTITHREADED 1
#define MOC_MULTITHREADED 0
#if MOC_MULTITHREADED
class CullingThreadpool;

View file

@ -2316,6 +2316,7 @@ void idRenderSystemLocal::Init()
#if MOC_MULTITHREADED
maskedOcclusionThreaded = new CullingThreadpool( 2, 10, 6, 128 );
maskedOcclusionThreaded->SetBuffer( maskedOcclusionCulling );
maskedOcclusionThreaded->WakeThreads();
#endif
R_MakeZeroOneCubeTrisForMaskedOcclusionCulling();

View file

@ -292,7 +292,6 @@ 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;
@ -314,37 +313,24 @@ static void R_AddSingleLight( viewLight_t* vLight )
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
// backface none so objects are still visible where we run into
#if MOC_MULTITHREADED
tr.maskedOcclusionThreaded->SetMatrix( NULL );
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionThreaded->TestTriangles( ( float* )triVerts, triIndices, 1, MaskedOcclusionCulling::BACKFACE_NONE );
tr.maskedOcclusionThreaded->SetMatrix( NULL );
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionThreaded->TestTriangles( ( float* )triVerts, tr.maskedZeroOneCubeIndexes, 12, MaskedOcclusionCulling::BACKFACE_NONE );
#else
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, tr.maskedZeroOneCubeIndexes, 12, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
#endif
if( result == MaskedOcclusionCulling::VISIBLE )
{
maskVisible = true;
}
#else
// draw for debugging
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
maskVisible = true;
#endif
}
if( !maskVisible )
if( result != MaskedOcclusionCulling::VISIBLE )
{
tr.pc.c_mocCulledLights += 1;
return;
}
#else
// draw for debugging
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
maskVisible = true;
#endif
}
else
{

View file

@ -701,11 +701,10 @@ void R_AddSingleModel( viewEntity_t* vEntity )
// RB: test surface visibility by drawing the triangles of the bounds
if( r_useMaskedOcclusionCulling.GetBool() && !viewInsideSurface && !viewDef->isMirror && !viewDef->isSubview )
{
#if 1
if( !model->IsStaticWorldModel() && !renderEntity->weaponDepthHack && renderEntity->modelDepthHack == 0.0f )
if( //!model->IsStaticWorldModel() &&
!renderEntity->weaponDepthHack && renderEntity->modelDepthHack == 0.0f )
{
idVec4 triVerts[8];
unsigned int triIndices[] = { 0, 1, 2 };
tr.pc.c_mocIndexes += 36;
tr.pc.c_mocVerts += 8;
@ -736,8 +735,6 @@ 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;
for( int i = 0; i < 8; i++ )
@ -746,56 +743,20 @@ void R_AddSingleModel( viewEntity_t* vEntity )
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
// backface none so objects are still visible where we run into
#if MOC_MULTITHREADED
tr.maskedOcclusionThreaded->SetMatrix( NULL );
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionThreaded->TestTriangles( ( float* )triVerts, triIndices, 1, MaskedOcclusionCulling::BACKFACE_NONE );
tr.maskedOcclusionThreaded->SetMatrix( NULL );
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionThreaded->TestTriangles( ( float* )triVerts, tr.maskedZeroOneCubeIndexes, 12, MaskedOcclusionCulling::BACKFACE_NONE );
#else
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, tr.maskedZeroOneCubeIndexes, 12, NULL, MaskedOcclusionCulling::BACKFACE_NONE );
#endif
if( result == MaskedOcclusionCulling::VISIBLE )
{
maskVisible = true;
}
}
if( !maskVisible )
if( result != MaskedOcclusionCulling::VISIBLE )
{
tr.pc.c_mocCulledSurfaces += 1;
surfaceDirectlyVisible = false;
}
}
#else
{
idVec4 triVerts[3];
unsigned int triIndices[] = { 0, 1, 2 };
tr.pc.c_mocIndexes += tri->numIndexes;
tr.pc.c_mocVerts += tri->numIndexes;
for( int i = 0, face = 0; i < tri->numIndexes; i += 3, face++ )
{
const idDrawVert& v0 = tri->verts[tri->indexes[i + 0]];
const idDrawVert& v1 = tri->verts[tri->indexes[i + 1]];
const idDrawVert& v2 = tri->verts[tri->indexes[i + 2]];
// transform to clip space
vEntity->unjitteredMVP.TransformPoint( idVec4( v0.xyz.x, v0.xyz.y, v0.xyz.z, 1 ), triVerts[0] );
vEntity->unjitteredMVP.TransformPoint( idVec4( v1.xyz.x, v1.xyz.y, v1.xyz.z, 1 ), triVerts[1] );
vEntity->unjitteredMVP.TransformPoint( idVec4( v2.xyz.x, v2.xyz.y, v2.xyz.z, 1 ), triVerts[2] );
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
}
}
#endif
}
#endif // #if defined(USE_INTRINSICS_SSE)

View file

@ -335,31 +335,12 @@ void R_RenderSingleModel( viewEntity_t* vEntity )
{
// render to masked occlusion buffer
if( !gpuSkinned )
//if( model->IsStaticWorldModel() )
//if( !gpuSkinned )
if( model->IsStaticWorldModel() )
{
#if 0
// super simple bruteforce and slow
idVec4 triVerts[3];
unsigned int triIndices[] = { 0, 1, 2 };
tr.pc.c_mocIndexes += tri->numIndexes;
tr.pc.c_mocVerts += tri->numIndexes;
for( int i = 0, face = 0; i < tri->numIndexes; i += 3, face++ )
{
const idDrawVert& v0 = tri->verts[tri->indexes[i + 0]];
const idDrawVert& v1 = tri->verts[tri->indexes[i + 1]];
const idDrawVert& v2 = tri->verts[tri->indexes[i + 2]];
// transform to clip space
vEntity->unjitteredMVP.TransformPoint( idVec4( v0.xyz.x, v0.xyz.y, v0.xyz.z, 1 ), triVerts[0] );
vEntity->unjitteredMVP.TransformPoint( idVec4( v1.xyz.x, v1.xyz.y, v1.xyz.z, 1 ), triVerts[1] );
vEntity->unjitteredMVP.TransformPoint( idVec4( v2.xyz.x, v2.xyz.y, v2.xyz.z, 1 ), triVerts[2] );
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
}
#else
R_CreateMaskedOcclusionCullingTris( tri );
idRenderMatrix mvp;
@ -370,8 +351,6 @@ void R_RenderSingleModel( viewEntity_t* vEntity )
tr.maskedOcclusionThreaded->RenderTriangles( tri->mocVerts->ToFloatPtr(), tri->mocIndexes, tri->numIndexes / 3, MaskedOcclusionCulling::BACKFACE_CCW, MaskedOcclusionCulling::CLIP_PLANE_ALL );
#else
tr.maskedOcclusionCulling->RenderTriangles( tri->mocVerts->ToFloatPtr(), tri->mocIndexes, tri->numIndexes / 3, ( float* )&mvp[0][0], MaskedOcclusionCulling::BACKFACE_CCW, MaskedOcclusionCulling::CLIP_PLANE_ALL, MaskedOcclusionCulling::VertexLayout( 16, 4, 8 ) );
#endif
#endif
}
#if 0
@ -407,7 +386,6 @@ void R_RenderSingleModel( viewEntity_t* vEntity )
idRenderMatrix invProjectMVPMatrix;
idRenderMatrix::Multiply( viewDef->worldSpace.unjitteredMVP, inverseBaseModelProject, invProjectMVPMatrix );
#if 1
// NOTE: unit cube instead of zeroToOne cube
idVec4* verts = tr.maskedUnitCubeVerts;
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
@ -424,14 +402,6 @@ void R_RenderSingleModel( viewEntity_t* vEntity )
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
}
#else
// TODO get faster alternative working
idRenderMatrix invProjectMVPMatrix2;
idRenderMatrix::Transpose( invProjectMVPMatrix, invProjectMVPMatrix2 );
tr.maskedOcclusionCulling->RenderTriangles( ( float* )tr.maskedZeroOneCubeVerts, tr.maskedZeroOneCubeIndexes, 12, ( float* )&invProjectMVPMatrix2[0][0], MaskedOcclusionCulling::BACKFACE_NONE, MaskedOcclusionCulling::CLIP_PLANE_ALL, MaskedOcclusionCulling::VertexLayout( 16, 4, 8 ) );
#endif
}
#endif