From e6960cb87675798e59d840dfaa6307abc683aef7 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Fri, 8 Nov 2019 20:09:57 +0100 Subject: [PATCH] Fixed rendering of stencil shadows with Vulkan --- neo/idlib/geometry/RenderMatrix.cpp | 9 ++++++- neo/renderer/RenderBackend.cpp | 41 ++++++++++++++++++++--------- neo/renderer/RenderBackend.h | 2 +- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/neo/idlib/geometry/RenderMatrix.cpp b/neo/idlib/geometry/RenderMatrix.cpp index 5ee29b0f..9b795b09 100644 --- a/neo/idlib/geometry/RenderMatrix.cpp +++ b/neo/idlib/geometry/RenderMatrix.cpp @@ -51,7 +51,14 @@ If you have questions concerning this license or the applicable additional terms #define RENDER_MATRIX_INFINITY 1e30f // NOTE: cannot initiaize a vec_float4 with idMath::INFINITY on the SPU #define RENDER_MATRIX_PROJECTION_EPSILON 0.1f -#define CLIP_SPACE_OGL // the OpenGL clip space Z is in the range [-1, 1] +//#define CLIP_SPACE_OGL // the OpenGL clip space Z is in the range [-1, 1] + +// RB: Vulkan requires the clip space Z is in the range [0, 1] +// This change is especially important for all kinds of light bounding box -> clip space transformations so +// the depth bounding tests clipping tests work properly +#if defined( USE_VULKAN ) +#define CLIP_SPACE_D3D 1 +#endif /* ================================================================================================ diff --git a/neo/renderer/RenderBackend.cpp b/neo/renderer/RenderBackend.cpp index 08c92459..8d019d18 100644 --- a/neo/renderer/RenderBackend.cpp +++ b/neo/renderer/RenderBackend.cpp @@ -1425,12 +1425,24 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view // perform setup here that will be constant for all interactions if( performStencilTest ) { - GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | depthFunc | GLS_STENCIL_FUNC_EQUAL | GLS_STENCIL_MAKE_REF( STENCIL_SHADOW_TEST_VALUE ) | GLS_STENCIL_MAKE_MASK( STENCIL_SHADOW_MASK_VALUE ) ); - + GL_State( + GLS_SRCBLEND_ONE | + GLS_DSTBLEND_ONE | + GLS_DEPTHMASK | + depthFunc | + GLS_STENCIL_FUNC_EQUAL | + GLS_STENCIL_MAKE_REF( STENCIL_SHADOW_TEST_VALUE ) | + GLS_STENCIL_MAKE_MASK( STENCIL_SHADOW_MASK_VALUE ) ); + } else { - GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | depthFunc | GLS_STENCIL_FUNC_ALWAYS ); + GL_State( + GLS_SRCBLEND_ONE | + GLS_DSTBLEND_ONE | + GLS_DEPTHMASK | + depthFunc | + GLS_STENCIL_FUNC_ALWAYS ); } // some rare lights have multiple animating stages, loop over them outside the surface list @@ -2549,7 +2561,7 @@ void idRenderBackend::StencilShadowPass( const drawSurf_t* drawSurfs, const view // cleanup the shadow specific rendering state - GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_FRONTSIDED ); + GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_FRONTSIDED ); // reset depth bounds if( r_useShadowDepthBounds.GetBool() ) @@ -2591,13 +2603,17 @@ void idRenderBackend::StencilSelectLight( const viewLight_t* vLight ) // clear stencil buffer to 0 (not drawable) uint64 glStateMinusStencil = GL_GetCurrentStateMinusStencil(); - GL_State( glStateMinusStencil | GLS_STENCIL_FUNC_ALWAYS | GLS_STENCIL_MAKE_REF( STENCIL_SHADOW_TEST_VALUE ) | GLS_STENCIL_MAKE_MASK( STENCIL_SHADOW_MASK_VALUE ) ); // make sure stencil mask passes for the clear + GL_State( + glStateMinusStencil | + GLS_STENCIL_FUNC_ALWAYS | + GLS_STENCIL_MAKE_REF( STENCIL_SHADOW_TEST_VALUE ) | + GLS_STENCIL_MAKE_MASK( STENCIL_SHADOW_MASK_VALUE ) ); // make sure stencil mask passes for the clear + GL_Clear( false, false, true, 0, 0.0f, 0.0f, 0.0f, 0.0f, false ); // clear to 0 for stencil select // set the depthbounds GL_DepthBoundsTest( vLight->scissorRect.zmin, vLight->scissorRect.zmax ); - GL_State( GLS_COLORMASK | GLS_ALPHAMASK | @@ -2605,6 +2621,8 @@ void idRenderBackend::StencilSelectLight( const viewLight_t* vLight ) GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS | GLS_STENCIL_FUNC_ALWAYS | + GLS_STENCIL_OP_FAIL_KEEP | GLS_STENCIL_OP_ZFAIL_REPLACE | GLS_STENCIL_OP_PASS_ZERO | + GLS_BACK_STENCIL_OP_FAIL_KEEP | GLS_BACK_STENCIL_OP_ZFAIL_ZERO | GLS_BACK_STENCIL_OP_PASS_REPLACE | GLS_STENCIL_MAKE_REF( STENCIL_SHADOW_TEST_VALUE ) | GLS_STENCIL_MAKE_MASK( STENCIL_SHADOW_MASK_VALUE ) ); @@ -2624,11 +2642,10 @@ void idRenderBackend::StencilSelectLight( const viewLight_t* vLight ) DrawElementsWithCounters( &zeroOneCubeSurface ); // reset stencil state - GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_FRONTSIDED ); + GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_FRONTSIDED ); renderProgManager.Unbind(); - // unset the depthbounds GL_DepthBoundsTest( 0.0f, 0.0f ); @@ -2766,17 +2783,17 @@ void idRenderBackend::ShadowMapPass( const drawSurf_t* drawSurfs, const viewLigh switch( r_shadowMapOccluderFacing.GetInteger() ) { case 0: - GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_FRONTSIDED ); + GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_FRONTSIDED ); GL_PolygonOffset( r_shadowMapPolygonFactor.GetFloat(), r_shadowMapPolygonOffset.GetFloat() ); break; case 1: - GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_BACKSIDED ); + GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_BACKSIDED ); GL_PolygonOffset( -r_shadowMapPolygonFactor.GetFloat(), -r_shadowMapPolygonOffset.GetFloat() ); break; default: - GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_TWOSIDED ); + GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_TWOSIDED ); GL_PolygonOffset( r_shadowMapPolygonFactor.GetFloat(), r_shadowMapPolygonOffset.GetFloat() ); break; } @@ -4219,7 +4236,7 @@ void idRenderBackend::FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* d zeroOneCubeSurface.scissorRect = viewDef->scissor; T_BasicFog( &zeroOneCubeSurface, fogPlanes, &vLight->inverseBaseLightProject ); - GL_State( glStateBits & ~( GLS_CULL_MASK ) | GLS_CULL_FRONTSIDED ); + GL_State( ( glStateBits & ~( GLS_CULL_MASK ) ) | GLS_CULL_FRONTSIDED ); GL_SelectTexture( 0 ); diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index 2b0c9d95..5c303ae8 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -4,7 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2016-2017 Dustin Land -Copyright (C) 2017 Robert Beckebans +Copyright (C) 2017-2019 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").