diff options
author | Jesse Buhagiar <jooster669@gmail.com> | 2022-01-15 13:40:15 +1100 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2022-01-18 01:48:51 +0200 |
commit | fc8dd0bf68fab7d5d79e4e2fa13a51169df80da2 (patch) | |
tree | 2aa308cd38350437386a1fc345fba2150ea7737e /Userland/Libraries/LibSoftGPU | |
parent | 38fc7361ca795e6c050a0c524e640f130670c129 (diff) | |
download | serenity-fc8dd0bf68fab7d5d79e4e2fa13a51169df80da2.zip |
LibSoftGPU: Use correct position for `vertex_to_light`
The spec has a few stipulations on what this value should actually be,
and hence we should follow it accordingly.
Diffstat (limited to 'Userland/Libraries/LibSoftGPU')
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Device.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index dedfbb24e0..3dee3ea959 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -807,19 +807,37 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const& if (!light.is_enabled) continue; - FloatVector4 vertex_to_light; + // We need to save the length here because the attenuation factor requires a non + // normalized vector! + auto sgi_arrow_operator = [](FloatVector4 const& p1, FloatVector4 const& p2, float& saved_length) { + if ((p1.w() != 0.0f) && (p2.w() == 0.0f)) { + saved_length = p2.length(); + return (p2 / saved_length).xyz(); + } else if ((p1.w() == 0.0f) && (p2.w() != 0.0f)) { + saved_length = p2.length(); + return -(p1 / saved_length).xyz(); + } else { + // FIXME: The OpenGL 1.5 spec says nothing about the case where P1 and P2 BOTH have a w value of 1, which would + // then mean the light position has an implicit value of (0, 0, 0, 0). This doesn't make any logical sense, and it most likely + // a typographical error. Most other GL implementations seem to just fix it to the distance from the vertex to the light, which + // seems to work just fine. + // If somebody with more insight about this could clarify this eventually, that'd be great. + auto distance = (p2 - p1); + saved_length = distance.length(); + return (distance / saved_length).xyz(); + } + }; + + float vector_length = 0.0f; + FloatVector3 vertex_to_light = sgi_arrow_operator(vertex.eye_coordinates, light.position, vector_length); // Light attenuation value. float light_attenuation_factor = 1.0f; if (light.position.w() != 0.0f) { - vertex_to_light = light.position - vertex.eye_coordinates; auto const vertex_to_light_length = vertex_to_light.length(); auto const vertex_to_light_length_squared = vertex_to_light_length * vertex_to_light_length; light_attenuation_factor = 1.0f / (light.constant_attenuation + (light.linear_attenuation * vertex_to_light_length) + (light.quadratic_attenuation * vertex_to_light_length_squared)); - vertex_to_light = vertex_to_light / vertex_to_light_length; - } else { - vertex_to_light = light.position.normalized(); } // Spotlight factor |