Skip to content

Commit

Permalink
LibSoftGPU: Use eye coordinates for fog calculation
Browse files Browse the repository at this point in the history
Now that we calculate and store eye coordinates for each vertex, we
should use their `z` values for the fragment depth used in further fog
calculations.

This fixes the fog in Tux Racer :^)
  • Loading branch information
gmta authored and awesomekling committed Dec 30, 2021
1 parent fef7f71 commit 69da279
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions Userland/Libraries/LibSoftGPU/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re
FloatVector4 pixel_staging[RASTERIZER_BLOCK_SIZE][RASTERIZER_BLOCK_SIZE];
float depth_staging[RASTERIZER_BLOCK_SIZE][RASTERIZER_BLOCK_SIZE];

// Fog depths
float const vertex0_eye_absz = fabs(vertex0.eye_coordinates.z());
float const vertex1_eye_absz = fabs(vertex1.eye_coordinates.z());
float const vertex2_eye_absz = fabs(vertex2.eye_coordinates.z());

// FIXME: implement stencil testing

// Iterate over all blocks within the bounds of the triangle
Expand Down Expand Up @@ -390,10 +395,13 @@ static void rasterize_triangle(const RasterizerOptions& options, Gfx::Bitmap& re
auto uv = interpolate(vertex0.tex_coord, vertex1.tex_coord, vertex2.tex_coord, barycentric);

// Calculate depth of fragment for fog
float z = interpolate(triangle.vertices[0].position.z(), triangle.vertices[1].position.z(), triangle.vertices[2].position.z(), barycentric);
z = options.depth_min + (options.depth_max - options.depth_min) * (z + 1) / 2;
//
// OpenGL 1.5 spec chapter 3.10: "An implementation may choose to approximate the
// eye-coordinate distance from the eye to each fragment center by |Ze|."

float fog_fragment_depth = interpolate(vertex0_eye_absz, vertex1_eye_absz, vertex2_eye_absz, barycentric);

*pixel = pixel_shader(uv, vertex_color, z);
*pixel = pixel_shader(uv, vertex_color, fog_fragment_depth);
}
}

Expand Down Expand Up @@ -707,7 +715,7 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&

void Device::submit_triangle(const Triangle& triangle, Vector<size_t> const& enabled_texture_units)
{
rasterize_triangle(m_options, *m_render_target, *m_depth_buffer, triangle, [this, &enabled_texture_units](FloatVector4 const& uv, FloatVector4 const& color, float z) -> FloatVector4 {
rasterize_triangle(m_options, *m_render_target, *m_depth_buffer, triangle, [this, &enabled_texture_units](FloatVector4 const& uv, FloatVector4 const& color, float fog_depth) -> FloatVector4 {
FloatVector4 fragment = color;

for (size_t i : enabled_texture_units) {
Expand Down Expand Up @@ -743,13 +751,13 @@ void Device::submit_triangle(const Triangle& triangle, Vector<size_t> const& ena
float factor = 0.0f;
switch (m_options.fog_mode) {
case FogMode::Linear:
factor = (m_options.fog_end - z) / (m_options.fog_end - m_options.fog_start);
factor = (m_options.fog_end - fog_depth) / (m_options.fog_end - m_options.fog_start);
break;
case FogMode::Exp:
factor = exp(-((m_options.fog_density * z)));
factor = expf(-m_options.fog_density * fog_depth);
break;
case FogMode::Exp2:
factor = exp(-((m_options.fog_density * z) * (m_options.fog_density * z)));
factor = expf(-((m_options.fog_density * fog_depth) * (m_options.fog_density * fog_depth)));
break;
default:
VERIFY_NOT_REACHED();
Expand Down

0 comments on commit 69da279

Please sign in to comment.