mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 06:34:10 +00:00
Query only draw surface boxes with MOC
This commit is contained in:
parent
dba7404eff
commit
fc6c1fef7a
5 changed files with 181 additions and 122 deletions
|
@ -350,7 +350,7 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
if( com_showFPS.GetInteger() > 2 )
|
||||
{
|
||||
statsWindowWidth += 230;
|
||||
statsWindowHeight += 135;
|
||||
statsWindowHeight += 140;
|
||||
}
|
||||
|
||||
ImVec2 pos;
|
||||
|
|
|
@ -1046,8 +1046,8 @@ public:
|
|||
idRenderBackend backend;
|
||||
|
||||
MaskedOcclusionCulling* maskedOcclusionCulling;
|
||||
idVec4 maskZeroOneCubeVerts[8];
|
||||
unsigned int maskZeroOneCubeIndexes[36];
|
||||
idVec4 maskedZeroOneCubeVerts[8];
|
||||
unsigned int maskedZeroOneCubeIndexes[36];
|
||||
|
||||
private:
|
||||
bool bInitialized;
|
||||
|
@ -1204,9 +1204,9 @@ extern idCVar r_debugRenderToTexture;
|
|||
extern idCVar stereoRender_enable;
|
||||
extern idCVar stereoRender_deGhost; // subtract from opposite eye to reduce ghosting
|
||||
|
||||
// RB begin
|
||||
extern idCVar r_useGPUSkinning;
|
||||
|
||||
// RB begin
|
||||
extern idCVar r_shadowMapAtlasSize;
|
||||
extern idCVar r_shadowMapFrustumFOV;
|
||||
extern idCVar r_shadowMapSingleSide;
|
||||
|
@ -1267,6 +1267,8 @@ extern idCVar r_useCRTPostFX;
|
|||
extern idCVar r_crtCurvature;
|
||||
extern idCVar r_crtVignette;
|
||||
|
||||
extern idCVar r_useMaskedOcclusionCulling;
|
||||
|
||||
enum RenderMode
|
||||
{
|
||||
RENDERMODE_DOOM,
|
||||
|
|
|
@ -305,6 +305,8 @@ idCVar r_renderMode( "r_renderMode", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_IN
|
|||
|
||||
idCVar r_psxVertexJitter( "r_psxVertexJitter", "0.5", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "", 0.0f, 0.75f );
|
||||
idCVar r_psxAffineTextures( "r_psxAffineTextures", "1", CVAR_RENDERER | CVAR_FLOAT | CVAR_NEW, "" );
|
||||
|
||||
idCVar r_useMaskedOcclusionCulling( "r_useMaskedOcclusionCulling", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_NEW, "SIMD optimized software culling by Intel" );
|
||||
// RB end
|
||||
|
||||
const char* fileExten[4] = { "tga", "png", "jpg", "exr" };
|
||||
|
@ -1787,6 +1789,13 @@ void idRenderSystemLocal::Clear()
|
|||
envprobeJobList = NULL;
|
||||
envprobeJobs.Clear();
|
||||
lightGridJobs.Clear();
|
||||
|
||||
// destroy occlusion culling object and free hierarchical z-buffer
|
||||
if( maskedOcclusionCulling != NULL )
|
||||
{
|
||||
MaskedOcclusionCulling::Destroy( maskedOcclusionCulling );
|
||||
maskedOcclusionCulling = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1936,9 +1945,7 @@ static srfTriangles_t* R_MakeZeroOneCubeTris()
|
|||
// RB begin
|
||||
static void R_MakeZeroOneCubeTrisForMaskedOcclusionCulling()
|
||||
{
|
||||
//idDrawVert* verts = tri->verts;
|
||||
|
||||
const float low = 0.0f;
|
||||
const float low = -1.0f;
|
||||
const float high = 1.0f;
|
||||
|
||||
idVec3 center( 0.0f );
|
||||
|
@ -1949,7 +1956,7 @@ static void R_MakeZeroOneCubeTrisForMaskedOcclusionCulling()
|
|||
idVec3 mz( 0.0f, 0.0f, low );
|
||||
idVec3 pz( 0.0f, 0.0f, high );
|
||||
|
||||
idVec4* verts = tr.maskZeroOneCubeVerts;
|
||||
idVec4* verts = tr.maskedZeroOneCubeVerts;
|
||||
|
||||
verts[0].ToVec3() = center + mx + my + mz;
|
||||
verts[1].ToVec3() = center + px + my + mz;
|
||||
|
@ -1969,7 +1976,7 @@ static void R_MakeZeroOneCubeTrisForMaskedOcclusionCulling()
|
|||
verts[6].w = 1;
|
||||
verts[7].w = 1;
|
||||
|
||||
unsigned int* indexes = tr.maskZeroOneCubeIndexes;
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
|
||||
// bottom
|
||||
indexes[ 0 * 3 + 0] = 2;
|
||||
|
|
|
@ -672,94 +672,92 @@ void R_AddSingleModel( viewEntity_t* vEntity )
|
|||
// individual surfaces.
|
||||
bool surfaceDirectlyVisible = modelIsVisible && !idRenderMatrix::CullBoundsToMVP( vEntity->mvp, tri->bounds );
|
||||
|
||||
#if 0
|
||||
// RB: test surface visibility by drawing the triangles of the bounds
|
||||
if( tr.maskedOcclusionCulling != NULL )
|
||||
{
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::CreateFromOriginAxis( renderEntity->origin, renderEntity->axis, modelRenderMatrix );
|
||||
|
||||
idRenderMatrix inverseBaseModelProject;
|
||||
idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, tri->bounds, inverseBaseModelProject );
|
||||
|
||||
idRenderMatrix invProjectMVPMatrix;
|
||||
idRenderMatrix::Multiply( viewDef->worldSpace.mvp, inverseBaseModelProject, invProjectMVPMatrix );
|
||||
|
||||
idRenderMatrix invProjectMVPMatrix2;
|
||||
idRenderMatrix::Transpose( invProjectMVPMatrix, invProjectMVPMatrix2 );
|
||||
|
||||
// query the triangle
|
||||
MaskedOcclusionCulling::CullingResult result;
|
||||
result = tr.maskedOcclusionCulling->TestTriangles( ( float* )tr.maskZeroOneCubeVerts, tr.maskZeroOneCubeIndexes, 36, ( float* )&invProjectMVPMatrix2[0][0], MaskedOcclusionCulling::BACKFACE_CCW );
|
||||
if( result == MaskedOcclusionCulling::OCCLUDED )
|
||||
{
|
||||
surfaceDirectlyVisible = false;
|
||||
tr.pc.c_mocCulls += 1;
|
||||
}
|
||||
}
|
||||
#elif 1
|
||||
{
|
||||
idVec4 triVerts[3];
|
||||
unsigned int triIndices[] = { 0, 1, 2 };
|
||||
|
||||
tr.pc.c_mocIndexes += tri->numIndexes;
|
||||
tr.pc.c_mocVerts += tri->numIndexes;
|
||||
|
||||
tr.pc.c_mocTests += 1;
|
||||
|
||||
bool maskVisible = false;
|
||||
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] );
|
||||
|
||||
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
|
||||
if( result == MaskedOcclusionCulling::VISIBLE )
|
||||
{
|
||||
maskVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !maskVisible )
|
||||
{
|
||||
tr.pc.c_mocCulls += 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->mvp.TransformPoint( idVec4( v0.xyz.x, v0.xyz.y, v0.xyz.z, 1 ), triVerts[0] );
|
||||
vEntity->mvp.TransformPoint( idVec4( v1.xyz.x, v1.xyz.y, v1.xyz.z, 1 ), triVerts[1] );
|
||||
vEntity->mvp.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
|
||||
|
||||
|
||||
// RB: added check wether GPU skinning is available at all
|
||||
const bool gpuSkinned = ( tri->staticModelWithJoints != NULL && r_useGPUSkinning.GetBool() );
|
||||
// RB end
|
||||
|
||||
// RB: test surface visibility by drawing the triangles of the bounds
|
||||
if( r_useMaskedOcclusionCulling.GetBool() )
|
||||
{
|
||||
#if 1
|
||||
if( !model->IsStaticWorldModel() && !renderEntity->weaponDepthHack && renderEntity->modelDepthHack == 0.0f )
|
||||
{
|
||||
idVec4 triVerts[3];
|
||||
unsigned int triIndices[] = { 0, 1, 2 };
|
||||
|
||||
tr.pc.c_mocIndexes += 36;
|
||||
tr.pc.c_mocVerts += 8;
|
||||
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::CreateFromOriginAxis( renderEntity->origin, renderEntity->axis, modelRenderMatrix );
|
||||
|
||||
const float size = 16.0f;
|
||||
idBounds debugBounds( idVec3( -size ), idVec3( size ) );
|
||||
//debugBounds = vEntity->entityDef->localReferenceBounds;
|
||||
debugBounds = tri->bounds;
|
||||
|
||||
idRenderMatrix inverseBaseModelProject;
|
||||
idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, debugBounds, inverseBaseModelProject );
|
||||
|
||||
idRenderMatrix invProjectMVPMatrix;
|
||||
idRenderMatrix::Multiply( viewDef->worldSpace.unjitteredMVP, inverseBaseModelProject, invProjectMVPMatrix );
|
||||
|
||||
tr.pc.c_mocTests += 1;
|
||||
|
||||
bool maskVisible = false;
|
||||
idVec4* verts = tr.maskedZeroOneCubeVerts;
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
for( int i = 0, face = 0; i < 36; i += 3, face++ )
|
||||
{
|
||||
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] );
|
||||
|
||||
MaskedOcclusionCulling::CullingResult result = tr.maskedOcclusionCulling->TestTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
|
||||
if( result == MaskedOcclusionCulling::VISIBLE )
|
||||
{
|
||||
maskVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !maskVisible )
|
||||
{
|
||||
tr.pc.c_mocCulls += 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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------
|
||||
// base drawing surface
|
||||
|
|
|
@ -411,45 +411,92 @@ void R_RenderSingleModel( viewEntity_t* vEntity )
|
|||
|
||||
// RB: added check wether GPU skinning is available at all
|
||||
const bool gpuSkinned = ( tri->staticModelWithJoints != NULL && r_useGPUSkinning.GetBool() );
|
||||
// RB end
|
||||
|
||||
//--------------------------
|
||||
// base drawing surface
|
||||
//--------------------------
|
||||
const float* shaderRegisters = NULL;
|
||||
drawSurf_t* baseDrawSurf = NULL;
|
||||
if( surfaceDirectlyVisible && shader->IsDrawn() )
|
||||
if( surfaceDirectlyVisible && shader->IsDrawn() && shader->Coverage() == MC_OPAQUE && !renderEntity->weaponDepthHack && renderEntity->modelDepthHack == 0.0f )
|
||||
{
|
||||
// TODO render to masked occlusion buffer
|
||||
// render to masked occlusion buffer
|
||||
|
||||
//if( model->IsStaticWorldModel() )
|
||||
{
|
||||
// super simple bruteforce
|
||||
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] );
|
||||
|
||||
// tri->indexes is unsigned short instead of uint
|
||||
//triIndices[0] = tri->indexes[i + 0];
|
||||
//triIndices[1] = tri->indexes[i + 1];
|
||||
//triIndices[2] = tri->indexes[i + 2];
|
||||
|
||||
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
idVec4 triVerts[3];
|
||||
unsigned int triIndices[] = { 0, 1, 2 };
|
||||
|
||||
tr.pc.c_mocIndexes += 36;
|
||||
tr.pc.c_mocVerts += 8;
|
||||
|
||||
idRenderMatrix modelRenderMatrix;
|
||||
idRenderMatrix::CreateFromOriginAxis( renderEntity->origin, renderEntity->axis, modelRenderMatrix );
|
||||
|
||||
const float size = 16.0f;
|
||||
idBounds debugBounds( idVec3( -size ), idVec3( size ) );
|
||||
//debugBounds = vEntity->entityDef->localReferenceBounds;
|
||||
debugBounds = tri->bounds;
|
||||
|
||||
idRenderMatrix inverseBaseModelProject;
|
||||
idRenderMatrix::OffsetScaleForBounds( modelRenderMatrix, debugBounds, inverseBaseModelProject );
|
||||
|
||||
idRenderMatrix invProjectMVPMatrix;
|
||||
idRenderMatrix::Multiply( viewDef->worldSpace.unjitteredMVP, inverseBaseModelProject, invProjectMVPMatrix );
|
||||
|
||||
#if 1
|
||||
// super simple bruteforce
|
||||
idVec4 triVerts[3];
|
||||
unsigned int triIndices[] = { 0, 1, 2 };
|
||||
idVec4* verts = tr.maskedZeroOneCubeVerts;
|
||||
unsigned int* indexes = tr.maskedZeroOneCubeIndexes;
|
||||
for( int i = 0, face = 0; i < 36; i += 3, face++ )
|
||||
{
|
||||
const idVec4& v0 = verts[indexes[i + 0]];
|
||||
const idVec4& v1 = verts[indexes[i + 1]];
|
||||
const idVec4& v2 = verts[indexes[i + 2]];
|
||||
|
||||
tr.pc.c_mocIndexes += tri->numIndexes;
|
||||
tr.pc.c_mocVerts += tri->numIndexes;
|
||||
// transform to clip space
|
||||
invProjectMVPMatrix.TransformPoint( v0, triVerts[0] );
|
||||
invProjectMVPMatrix.TransformPoint( v1, triVerts[1] );
|
||||
invProjectMVPMatrix.TransformPoint( v2, triVerts[2] );
|
||||
|
||||
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]];
|
||||
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
|
||||
}
|
||||
#else
|
||||
|
||||
// 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] );
|
||||
// TODO get faster alternative working
|
||||
idRenderMatrix invProjectMVPMatrix2;
|
||||
idRenderMatrix::Transpose( invProjectMVPMatrix, invProjectMVPMatrix2 );
|
||||
|
||||
// tri->indexes is unsigned short instead of uint
|
||||
//triIndices[0] = tri->indexes[i + 0];
|
||||
//triIndices[1] = tri->indexes[i + 1];
|
||||
//triIndices[2] = tri->indexes[i + 2];
|
||||
|
||||
tr.maskedOcclusionCulling->RenderTriangles( ( float* )triVerts, triIndices, 1, NULL, MaskedOcclusionCulling::BACKFACE_CCW );
|
||||
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
|
||||
}
|
||||
|
||||
// TODO write faster alternative
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -526,6 +573,11 @@ void R_FillMaskedOcclusionBufferWithModels( viewDef_t* viewDef )
|
|||
{
|
||||
SCOPED_PROFILE_EVENT( "R_FillMaskedOcclusionBufferWithModels" );
|
||||
|
||||
if( !r_useMaskedOcclusionCulling.GetBool() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int viewWidth = viewDef->viewport.x2 - viewDef->viewport.x1 + 1;
|
||||
const int viewHeight = viewDef->viewport.y2 - viewDef->viewport.y1 + 1;
|
||||
|
||||
|
@ -562,7 +614,7 @@ void R_FillMaskedOcclusionBufferWithModels( viewDef_t* viewDef )
|
|||
// skip after rendering BSP area models
|
||||
if( !model->IsStaticWorldModel() )
|
||||
{
|
||||
continue;
|
||||
//continue;
|
||||
}
|
||||
|
||||
R_RenderSingleModel( vEntity );
|
||||
|
@ -612,6 +664,6 @@ CONSOLE_COMMAND( maskShot, "Dumping masked occlusion culling buffer", NULL )
|
|||
unsigned char* image = new unsigned char[width * height * 3];
|
||||
TonemapDepth( perPixelZBuffer, image, width, height );
|
||||
|
||||
R_WritePNG( "occlusion_buffer.png", image, 3, width, height, "fs_basepath" );
|
||||
R_WritePNG( "screenshots/soft_occlusion_buffer.png", image, 3, width, height, "fs_basepath" );
|
||||
delete[] image;
|
||||
}
|
Loading…
Reference in a new issue