Added r_forceShadowMapsOnAlphaTestedSurfaces 1

This commit is contained in:
Robert Beckebans 2014-05-11 14:36:51 +02:00
parent 0ca7667fd2
commit 2307a94d53
2 changed files with 133 additions and 11 deletions

View file

@ -2237,13 +2237,15 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL
uint64 glState = 0;
GL_PolygonOffset( r_shadowPolygonFactor.GetFloat(), -r_shadowPolygonOffset.GetFloat() );
//GL_PolygonOffset( r_shadowPolygonFactor.GetFloat(), -r_shadowPolygonOffset.GetFloat() );
// the actual stencil func will be set in the draw code, but we need to make sure it isn't
// disabled here, and that the value will get reset for the interactions without looking
// like a no-change-required
GL_State( glState | GLS_POLYGON_OFFSET );
//GL_State( glState | GLS_POLYGON_OFFSET );
GL_State( GLS_DEFAULT );
// Two Sided Stencil reduces two draw calls to one for slightly faster shadows
GL_Cull( CT_TWO_SIDED );
@ -2591,7 +2593,6 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL
if( drawSurf->space != backEnd.currentSpace )
{
idRenderMatrix modelRenderMatrix;
idRenderMatrix::Transpose( *( idRenderMatrix* )drawSurf->space->modelMatrix, modelRenderMatrix );
@ -2631,23 +2632,136 @@ static void RB_ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vL
backEnd.currentSpace = drawSurf->space;
}
if( drawSurf->jointCache )
bool didDraw = false;
const idMaterial* shader = drawSurf->material;
// get the expressions for conditionals / color / texcoords
const float* regs = drawSurf->shaderRegisters;
idVec4 color( 0, 0, 0, 1 );
uint64 surfGLState = 0;
// set polygon offset if necessary
if( shader->TestMaterialFlag( MF_POLYGONOFFSET ) )
{
renderProgManager.BindShader_DepthSkinned();
}
else
{
renderProgManager.BindShader_Depth();
surfGLState |= GLS_POLYGON_OFFSET;
GL_PolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
}
RB_DrawElementsWithCounters( drawSurf );
#if 1
if( shader->Coverage() == MC_PERFORATED )
{
// perforated surfaces may have multiple alpha tested stages
for( int stage = 0; stage < shader->GetNumStages(); stage++ )
{
const shaderStage_t* pStage = shader->GetStage( stage );
if( !pStage->hasAlphaTest )
{
continue;
}
// check the stage enable condition
if( regs[ pStage->conditionRegister ] == 0 )
{
continue;
}
// if we at least tried to draw an alpha tested stage,
// we won't draw the opaque surface
didDraw = true;
// set the alpha modulate
color[3] = regs[ pStage->color.registers[3] ];
// skip the entire stage if alpha would be black
if( color[3] <= 0.0f )
{
continue;
}
uint64 stageGLState = surfGLState;
// set privatePolygonOffset if necessary
if( pStage->privatePolygonOffset )
{
GL_PolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * pStage->privatePolygonOffset );
stageGLState |= GLS_POLYGON_OFFSET;
}
GL_Color( color );
#ifdef USE_CORE_PROFILE
GL_State( stageGLState );
idVec4 alphaTestValue( regs[ pStage->alphaTestRegister ] );
SetFragmentParm( RENDERPARM_ALPHA_TEST, alphaTestValue.ToFloatPtr() );
#else
GL_State( stageGLState | GLS_ALPHATEST_FUNC_GREATER | GLS_ALPHATEST_MAKE_REF( idMath::Ftob( 255.0f * regs[ pStage->alphaTestRegister ] ) ) );
#endif
if( drawSurf->jointCache )
{
renderProgManager.BindShader_TextureVertexColorSkinned();
}
else
{
renderProgManager.BindShader_TextureVertexColor();
}
RB_SetVertexColorParms( SVC_IGNORE );
// bind the texture
GL_SelectTexture( 0 );
pStage->texture.image->Bind();
// set texture matrix and texGens
RB_PrepareStageTexturing( pStage, drawSurf );
// must render with less-equal for Z-Cull to work properly
assert( ( GL_GetCurrentState() & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_LESS );
// draw it
RB_DrawElementsWithCounters( drawSurf );
// clean up
RB_FinishStageTexturing( pStage, drawSurf );
// unset privatePolygonOffset if necessary
if( pStage->privatePolygonOffset )
{
GL_PolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
}
}
}
#endif
if( !didDraw )
{
if( drawSurf->jointCache )
{
renderProgManager.BindShader_DepthSkinned();
}
else
{
renderProgManager.BindShader_Depth();
}
RB_DrawElementsWithCounters( drawSurf );
}
}
// cleanup the shadow specific rendering state
Framebuffer::BindNull();
renderProgManager.Unbind();
GL_State( GLS_DEFAULT );
GL_Cull( CT_FRONT_SIDED );
#ifdef USE_CORE_PROFILE
SetFragmentParm( RENDERPARM_ALPHA_TEST, vec4_zero.ToFloatPtr() );
#endif
}
/*

View file

@ -41,6 +41,9 @@ idCVar r_useShadowPreciseInsideTest( "r_useShadowPreciseInsideTest", "1", CVAR_R
idCVar r_cullDynamicShadowTriangles( "r_cullDynamicShadowTriangles", "1", CVAR_RENDERER | CVAR_BOOL, "cull occluder triangles that are outside the light frustum so they do not contribute to the dynamic shadow volume" );
idCVar r_cullDynamicLightTriangles( "r_cullDynamicLightTriangles", "1", CVAR_RENDERER | CVAR_BOOL, "cull surface triangles that are outside the light frustum so they do not get rendered for interactions" );
idCVar r_forceShadowCaps( "r_forceShadowCaps", "0", CVAR_RENDERER | CVAR_BOOL, "0 = skip rendering shadow caps if view is outside shadow volume, 1 = always render shadow caps" );
// RB begin
idCVar r_forceShadowMapsOnAlphaTestedSurfaces( "r_forceShadowMapsOnAlphaTestedSurfaces", "1", CVAR_RENDERER | CVAR_BOOL, "0 = same shadowing as with stencil shadows, 1 = ignore noshadows for alpha tested materials" );
// RB end
static const float CHECK_BOUNDS_EPSILON = 1.0f;
@ -912,7 +915,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
// surface shadows
//--------------------------
if( !shader->SurfaceCastsShadow() )
if( !shader->SurfaceCastsShadow() && !( r_useShadowMapping.GetBool() && r_forceShadowMapsOnAlphaTestedSurfaces.GetBool() && shader->Coverage() == MC_PERFORATED ) )
{
continue;
}
@ -1000,6 +1003,11 @@ void R_AddSingleModel( viewEntity_t* vEntity )
shadowDrawSurf->renderZFail = 0;
//shadowDrawSurf->shaderRegisters = baseDrawSurf->shaderRegisters;
if( shader->Coverage() == MC_PERFORATED )
{
R_SetupDrawSurfShader( shadowDrawSurf, shader, renderEntity );
}
R_SetupDrawSurfJoints( shadowDrawSurf, tri, shader );
// determine which linked list to add the shadow surface to