Fixed rendering of stencil shadows with Vulkan

This commit is contained in:
Robert Beckebans 2019-11-08 20:09:57 +01:00
parent 57f502d167
commit e6960cb876
3 changed files with 38 additions and 14 deletions

View file

@ -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
/*
================================================================================================

View file

@ -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 );

View file

@ -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").