gl4: depth test issue in non-autosort mode

Depth testing is done in the fragment shader so it shouldn't be done
in the a-buffer shader for the first pixel, or until the depth is updated.
Fixes flashlight and lightstorm effects in Alone in the Dark
This commit is contained in:
Flyinghead 2019-07-09 15:25:15 +02:00
parent d5e24d8aed
commit 632aa95c2d
3 changed files with 55 additions and 46 deletions

View File

@ -72,46 +72,53 @@ vec4 resolveAlphaBlend(ivec2 coords) { \n\
vec4 secondaryBuffer = vec4(0.0); // Secondary accumulation buffer \n\
float depth = 1.0; \n\
\n\
bool do_depth_test = false; \n\
for (int i = 0; i < num_frag; i++) \n\
{ \n\
const Pixel pixel = pixels[pixel_list[i]]; \n\
const PolyParam pp = tr_poly_params[getPolyNumber(pixel)]; \n\
#if DEPTH_SORTED != 1 \n\
const float frag_depth = pixel.depth; \n\
switch (getDepthFunc(pp)) \n\
if (do_depth_test) \n\
{ \n\
case 0: // Never \n\
continue; \n\
case 1: // Greater \n\
if (frag_depth <= depth) \n\
switch (getDepthFunc(pp)) \n\
{ \n\
case 0: // Never \n\
continue; \n\
break; \n\
case 2: // Equal \n\
if (frag_depth != depth) \n\
continue; \n\
break; \n\
case 3: // Greater or equal \n\
if (frag_depth < depth) \n\
continue; \n\
break; \n\
case 4: // Less \n\
if (frag_depth >= depth) \n\
continue; \n\
break; \n\
case 5: // Not equal \n\
if (frag_depth == depth) \n\
continue; \n\
break; \n\
case 6: // Less or equal \n\
if (frag_depth > depth) \n\
continue; \n\
break; \n\
case 7: // Always \n\
break; \n\
case 1: // Greater \n\
if (frag_depth <= depth) \n\
continue; \n\
break; \n\
case 2: // Equal \n\
if (frag_depth != depth) \n\
continue; \n\
break; \n\
case 3: // Greater or equal \n\
if (frag_depth < depth) \n\
continue; \n\
break; \n\
case 4: // Less \n\
if (frag_depth >= depth) \n\
continue; \n\
break; \n\
case 5: // Not equal \n\
if (frag_depth == depth) \n\
continue; \n\
break; \n\
case 6: // Less or equal \n\
if (frag_depth > depth) \n\
continue; \n\
break; \n\
case 7: // Always \n\
break; \n\
} \n\
} \n\
\n\
if (getDepthMask(pp)) \n\
{ \n\
depth = frag_depth; \n\
do_depth_test = true; \n\
} \n\
#endif \n\
bool area1 = false; \n\
bool shadowed = false; \n\
@ -207,7 +214,7 @@ void main(void) \n\
ivec2 coords = ivec2(gl_FragCoord.xy); \n\
// Compute and output final color for the frame buffer \n\
// Visualize the number of layers in use \n\
//FragColor = vec4(float(fillFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT, 0, 0, 1); \n\
//FragColor = vec4(float(fillAndSortFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT * 4, 0, 0, 1); \n\
FragColor = resolveAlphaBlend(coords); \n\
} \n\
";

View File

@ -103,7 +103,7 @@ static void SetTextureRepeatMode(int index, GLuint dir, u32 clamp, u32 mirror)
}
template <u32 Type, bool SortingEnabled>
static void SetGPState(const PolyParam* gp, int pass, u32 cflip=0)
static void SetGPState(PolyParam* gp, int pass)
{
if (gp->pcw.Texture && gp->tsp.FilterMode > 1)
{
@ -231,14 +231,14 @@ template <u32 Type, bool SortingEnabled>
//set cull mode !
//cflip is required when exploding triangles for triangle sorting
//gcflip is global clip flip, needed for when rendering to texture due to mirrored Y direction
SetCull(gp->isp.CullMode^cflip^gcflip);
SetCull(gp->isp.CullMode ^ gcflip);
//set Z mode, only if required
if (Type == ListType_Punch_Through || (Type == ListType_Translucent && SortingEnabled))
if (Type == ListType_Punch_Through)
{
glcache.DepthFunc(Zfunction[6]); // Greater or equal
}
else
else if (Type == ListType_Opaque)
{
glcache.DepthFunc(Zfunction[gp->isp.DepthMode]);
}
@ -246,7 +246,8 @@ template <u32 Type, bool SortingEnabled>
// Depth buffer is updated in pass 0 (and also in pass 1 for OP PT)
if (pass < 2)
{
// Ignore ZWriteDis for punch-through? fixes Worms World Party
// Z Write Disable seems to be ignored for punch-through polys
// Fixes Worms World Party, Bust-a-Move 4 and Re-Volt
if (Type == ListType_Punch_Through)
glcache.DepthMask(GL_TRUE);
else
@ -256,7 +257,7 @@ template <u32 Type, bool SortingEnabled>
glcache.DepthMask(GL_FALSE);
}
template <u32 Type, bool SortingEnabled>
template <u32 Type, bool SortingEnabled, bool OnlyAlwaysDepth>
static void DrawList(const List<PolyParam>& gply, int first, int count, int pass)
{
PolyParam* params = &gply.head()[first];
@ -279,7 +280,7 @@ static void DrawList(const List<PolyParam>& gply, int first, int count, int pass
continue;
}
}
if (pass == 0 && Type == ListType_Translucent && (params->isp.DepthMode != 7 || params->isp.ZWriteDis))
if (OnlyAlwaysDepth && (params->isp.DepthMode != 7 || params->isp.ZWriteDis))
{
params++;
continue;
@ -534,8 +535,8 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
glcache.Enable(GL_STENCIL_TEST);
glcache.StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
DrawList<ListType_Opaque, false>(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 0);
DrawList<ListType_Punch_Through, false>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 0);
DrawList<ListType_Opaque, false, false>(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 0);
DrawList<ListType_Punch_Through, false, false>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 0);
// Modifier volumes
if (settings.rend.ModifierVolumes)
@ -570,10 +571,10 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
glCheck();
//Opaque
DrawList<ListType_Opaque, false>(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 1);
DrawList<ListType_Opaque, false, false>(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 1);
//Alpha tested
DrawList<ListType_Punch_Through, false>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 1);
DrawList<ListType_Punch_Through, false, false>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 1);
// Unbind stencil
glActiveTexture(GL_TEXTURE3);
@ -597,7 +598,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glcache.Enable(GL_DEPTH_TEST);
glcache.DepthMask(GL_TRUE);
DrawList<ListType_Translucent, false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0);
DrawList<ListType_Translucent, false, true>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0);
}
//
// PASS 3: Render TR to a-buffers
@ -611,9 +612,9 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
//Alpha blended
if (current_pass.autosort)
DrawList<ListType_Translucent, true>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more
DrawList<ListType_Translucent, true, false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more
else
DrawList<ListType_Translucent, false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more
DrawList<ListType_Translucent, false, false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more
glCheck();
// Translucent modifier volumes
@ -632,9 +633,9 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
glcache.Enable(GL_DEPTH_TEST);
if (current_pass.autosort)
DrawList<ListType_Translucent, true>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0);
DrawList<ListType_Translucent, true, false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0);
else
DrawList<ListType_Translucent, false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0);
DrawList<ListType_Translucent, false, false>(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0);
//
// PASS 3c: Render a-buffer to temporary texture

View File

@ -264,7 +264,8 @@ __forceinline
glcache.DepthMask(GL_FALSE);
else
{
// Ignore ZWriteDis for punch-through? fixes Worms World Party
// Z Write Disable seems to be ignored for punch-through.
// Fixes Worms World Party, Bust-a-Move 4 and Re-Volt
if (Type == ListType_Punch_Through)
glcache.DepthMask(GL_TRUE);
else