mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 02:13:56 +09:00
LibSoftGPU: Implement depth offset factor
This implements the depth offset factor that you can set through e.g. OpenGL's `glPolygonOffset`. Without it, triangles might start to Z- fight amongst each other. This fixes the floor decals in Quake 3.
This commit is contained in:
parent
62d41d58d6
commit
b8c0ebccfd
Notes:
sideshowbarker
2024-07-17 11:06:04 +09:00
Author: https://github.com/gmta
Commit: b8c0ebccfd
Pull-request: https://github.com/SerenityOS/serenity/pull/13998
Reviewed-by: https://github.com/Quaker762 ✅
1 changed files with 37 additions and 5 deletions
|
@ -336,9 +336,6 @@ ALWAYS_INLINE void Device::rasterize(Gfx::IntRect& render_bounds, CB1 set_covera
|
||||||
};
|
};
|
||||||
if (m_options.enable_depth_test) {
|
if (m_options.enable_depth_test) {
|
||||||
set_quad_depth(quad);
|
set_quad_depth(quad);
|
||||||
// FIXME: Also apply depth_offset_factor which depends on the depth gradient
|
|
||||||
if (m_options.depth_offset_enabled)
|
|
||||||
quad.depth += m_options.depth_offset_constant * NumericLimits<float>::epsilon();
|
|
||||||
|
|
||||||
auto depth = load4_masked(depth_ptrs[0], depth_ptrs[1], depth_ptrs[2], depth_ptrs[3], quad.mask);
|
auto depth = load4_masked(depth_ptrs[0], depth_ptrs[1], depth_ptrs[2], depth_ptrs[3], quad.mask);
|
||||||
i32x4 depth_test_passed;
|
i32x4 depth_test_passed;
|
||||||
|
@ -742,6 +739,41 @@ void Device::rasterize_triangle(Triangle& triangle)
|
||||||
expand4(vertex2.window_coordinates.w()),
|
expand4(vertex2.window_coordinates.w()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Calculate depth offset to apply
|
||||||
|
float depth_offset = 0.f;
|
||||||
|
if (m_options.depth_offset_enabled) {
|
||||||
|
// Edge value deltas
|
||||||
|
auto edge_value_step_x = FloatVector3 {
|
||||||
|
static_cast<float>(v1.y() - v2.y()),
|
||||||
|
static_cast<float>(v2.y() - v0.y()),
|
||||||
|
static_cast<float>(v0.y() - v1.y()),
|
||||||
|
};
|
||||||
|
auto edge_value_step_y = FloatVector3 {
|
||||||
|
static_cast<float>(v2.x() - v1.x()),
|
||||||
|
static_cast<float>(v0.x() - v2.x()),
|
||||||
|
static_cast<float>(v1.x() - v0.x()),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Barycentric deltas
|
||||||
|
auto barycentric_step_x = edge_value_step_x * one_over_area;
|
||||||
|
auto barycentric_step_y = edge_value_step_y * one_over_area;
|
||||||
|
|
||||||
|
// Depth delta vector and slope (magnitude)
|
||||||
|
auto depth_coordinates = FloatVector3 {
|
||||||
|
vertex0.window_coordinates.z(),
|
||||||
|
vertex1.window_coordinates.z(),
|
||||||
|
vertex2.window_coordinates.z(),
|
||||||
|
};
|
||||||
|
auto depth_step = FloatVector2 {
|
||||||
|
depth_coordinates.dot(barycentric_step_x),
|
||||||
|
depth_coordinates.dot(barycentric_step_y),
|
||||||
|
};
|
||||||
|
auto depth_max_slope = depth_step.length();
|
||||||
|
|
||||||
|
// Calculate total depth offset
|
||||||
|
depth_offset = depth_max_slope * m_options.depth_offset_factor + NumericLimits<float>::epsilon() * m_options.depth_offset_constant;
|
||||||
|
}
|
||||||
|
|
||||||
rasterize(
|
rasterize(
|
||||||
render_bounds,
|
render_bounds,
|
||||||
[&](auto& quad) {
|
[&](auto& quad) {
|
||||||
|
@ -754,12 +786,12 @@ void Device::rasterize_triangle(Triangle& triangle)
|
||||||
to_f32x4(edge_values.z()),
|
to_f32x4(edge_values.z()),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[&one_over_area, &window_z_coordinates](auto& quad) {
|
[&](auto& quad) {
|
||||||
// Determine each edge's ratio to the total area
|
// Determine each edge's ratio to the total area
|
||||||
quad.barycentrics = quad.barycentrics * one_over_area;
|
quad.barycentrics = quad.barycentrics * one_over_area;
|
||||||
|
|
||||||
// Because the Z coordinates were divided by W, we can interpolate between them
|
// Because the Z coordinates were divided by W, we can interpolate between them
|
||||||
quad.depth = window_z_coordinates.dot(quad.barycentrics);
|
quad.depth = window_z_coordinates.dot(quad.barycentrics) + depth_offset;
|
||||||
},
|
},
|
||||||
[&](auto& quad) {
|
[&](auto& quad) {
|
||||||
auto const interpolated_reciprocal_w = window_w_coordinates.dot(quad.barycentrics);
|
auto const interpolated_reciprocal_w = window_w_coordinates.dot(quad.barycentrics);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue