diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.cpp b/src/rendering/polyrenderer/drawers/poly_triangle.cpp index 1c33fa077..d4b4610cb 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/poly_triangle.cpp @@ -257,6 +257,8 @@ void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPu PushConstants = &constants; + AlphaThreshold = clamp((int)(PushConstants->uAlphaThreshold * 255.0f + 0.5f), 0, 255) << 24; + numPolyLights = 0; if (constants.uLightIndex >= 0) { diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.h b/src/rendering/polyrenderer/drawers/poly_triangle.h index 227dab664..d3d5e15a0 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.h +++ b/src/rendering/polyrenderer/drawers/poly_triangle.h @@ -214,6 +214,7 @@ public: uint32_t FragColor[MAXWIDTH]; uint16_t lightarray[MAXWIDTH]; uint32_t dynlights[MAXWIDTH]; + uint8_t discard[MAXWIDTH]; } scanline; static PolyTriangleThreadData *Get(DrawerThread *thread); @@ -242,6 +243,7 @@ public: int SpecialEffect = EFF_NONE; int EffectState = 0; bool AlphaTest = false; + uint32_t AlphaThreshold = 0x7f000000; const PolyPushConstants* PushConstants = nullptr; const void *vertices = nullptr; diff --git a/src/rendering/polyrenderer/drawers/screen_triangle.cpp b/src/rendering/polyrenderer/drawers/screen_triangle.cpp index 2e3e1553f..0cb85a415 100644 --- a/src/rendering/polyrenderer/drawers/screen_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/screen_triangle.cpp @@ -451,6 +451,7 @@ static void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread) uint32_t* dest = (uint32_t*)thread->dest; uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch; uint32_t* fragcolor = thread->scanline.FragColor; + uint8_t* discard = thread->scanline.discard; for (int x = x0; x < x1; x++) { @@ -458,7 +459,7 @@ static void BlendColor(int y, int x0, int x1, PolyTriangleThreadData* thread) if (OptT::Flags & SWBLEND_AlphaTest) { - if (fragcolor[x] <= 0x7f000000) + if (discard[x]) continue; } @@ -540,9 +541,10 @@ static void WriteColor(int y, int x0, int x1, PolyTriangleThreadData* thread) } else { + uint8_t* discard = thread->scanline.discard; for (int x = x0; x < x1; x++) { - if (fragcolor[x] > 0x7f000000) + if (!discard[x]) line[x] = fragcolor[x]; } } @@ -587,10 +589,11 @@ static void WriteDepth(int y, int x0, int x1, PolyTriangleThreadData* thread) } else { + uint8_t* discard = thread->scanline.discard; uint32_t* fragcolor = thread->scanline.FragColor; for (int x = x0; x < x1; x++) { - if (fragcolor[x] > 0x7f000000) + if (!discard[x]) line[x] = w[x]; } } @@ -610,10 +613,11 @@ static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread) } else { + uint8_t* discard = thread->scanline.discard; uint32_t* fragcolor = thread->scanline.FragColor; for (int x = x0; x < x1; x++) { - if (fragcolor[x] > 0x7f000000) + if (!discard[x]) line[x] = value; } } @@ -790,10 +794,9 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) case TM_CLAMPY: for (int x = x0; x < x1; x++) { - if (v[x] >= 0.0 && v[x] <= 1.0) - fragcolor[x] = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); - else - fragcolor[x] = 0; + fragcolor[x] = SampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); + if (v[x] < 0.0 || v[x] > 1.0) + fragcolor[x] &= 0x00ffffff; } break; case TM_INVERTOPAQUE: @@ -878,6 +881,8 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) } } + uint32_t alphaThreshold = thread->AlphaThreshold; + uint8_t* discard = thread->scanline.discard; for (int x = x0; x < x1; x++) { uint32_t r = thread->scanline.vColorR[x]; @@ -891,6 +896,7 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) b += b >> 7; uint32_t texel = fragcolor[x]; + discard[x] = texel <= alphaThreshold; fragcolor[x] = MAKEARGB( (APART(texel) * a + 127) >> 8, (RPART(texel) * r + 127) >> 8,