LibSoftGPU: Improve depth interpolation precision

This should get rid of various artifacts when exact depth equality is
needed, such as when using GL_EQUAL or similar depth functions.
This commit is contained in:
Stephan Unverwerth authored and Nico Weber committed 2026-11-02 18:27:57 -05:00
1 parent 8e6e5a697c
commit ac779f06cc
3 files changed
+37 -3

No files matched your search

+34
View File
@@ -413,3 +413,37 @@ TEST_CASE(0013_fog_linear)
context->present();
expect_bitmap_equals_reference(context->frontbuffer(), "0013_fog_linear"sv);
}
TEST_CASE(0014_depth_consistency)
{
auto width = 99;
auto height = 99;
auto context = create_testing_context(width, height);
glClearColor(0.f, 1.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBegin(GL_TRIANGLES);
glColor3f(0.f, 0.f, 0.f);
glVertex3f(-.1f, 1.f, .5f);
glVertex3f(-1.f, -1.f, .5f);
glVertex3f(1.f, -1.f, .5f);
glEnd();
glBegin(GL_TRIANGLES);
glColor3f(1.f, 1.f, 1.f);
glVertex3f(.1f, 1.f, .5f);
glVertex3f(-1.f, -1.f, .5f);
glVertex3f(1.f, -1.f, .5f);
glEnd();
EXPECT_EQ(glGetError(), 0u);
context->present();
expect_bitmap_equals_reference(context->frontbuffer(), "0014_depth_consistency"sv);
}
+3 -3
View File
@@ -786,11 +786,11 @@ void Device::rasterize_triangle(Triangle& triangle)
};
},
[&](auto& quad) {
// Because the Z coordinates were divided by W, we can interpolate between them
quad.depth = AK::SIMD::clamp(window_z_coordinates.dot(quad.barycentrics) * one_over_area, 0.f, 1.f);
// Determine each edge's ratio to the total area
quad.barycentrics = quad.barycentrics * one_over_area;
// Because the Z coordinates were divided by W, we can interpolate between them
quad.depth = AK::SIMD::clamp(window_z_coordinates.dot(quad.barycentrics), 0.f, 1.f);
},
[&](auto& quad) {
auto const interpolated_reciprocal_w = window_w_coordinates.dot(quad.barycentrics);