Skip to content

Conversation

@Flarkk
Copy link
Contributor

@Flarkk Flarkk commented Jul 3, 2025

This PR partially solves #106312 and #107383 by ensuring that Projection's getters return the same values even when y_flip and/or reverse_z are applied.
However I couldn't find a way to support remap_z without disruption, which makes this PR of little help with Vulkan-style matrices Z ∈ [0; 1] (for instance with Forward+).

The fundamental issue is that #100209 only supports OpenGL-style matrices (negative Z-facing, Z ∈ [-1; 1], and Y upwards), which seemed reasonable considering all user-facing code follows this standard. This is not necessarily true in the buffers though, nor inside the callbacks of the Compositor.

I leave this PR in draft state so that whoever can take a look and share ideas.

At this stage I'm thinking of another approach :

  1. document that Projection's getters only support OpenGL-style matrices
  2. provide a way to transform back any matrix to its OpenGL form (i.e. the inverse of set_depth_correction)
  3. help users to figure out the form of the matrix when they access it (e.g. in the Compositor's callbacks) as it differs across renderers. They can then apply the right inverse transform before using the getters.

Of course this is under the assumption that we do not want to revert #100209, which is also an option although it is mathematically accurate (only more restrictive in terms of assumptions, which allows aggressive simplification).

@Chaosus Chaosus added this to the 4.x milestone Jul 4, 2025
@Flarkk Flarkk force-pushed the fix_corrected_projection branch from 2f671b3 to ddffe0d Compare July 4, 2025 12:06
@Flarkk
Copy link
Contributor Author

Flarkk commented Jul 4, 2025

For reference, here is the complete list of getters inconsistencies across all possible combinations of y_flip, reverse_z and remap_z :

Doctest log
===============================================================================
./tests/core/math/test_projection.h:472:
TEST CASE:  [Projection] Perspective values extraction

./tests/core/math/test_projection.h:483: WARNING: WARN( aspect == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -0.5 == Approx( 0.5 ) )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:481: WARNING: WARN( znear == doctest::Approx(1) ) is NOT correct!
  values: WARN( 50 == Approx( 1 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:482: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 1 == Approx( 50 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:481: WARNING: WARN( znear == doctest::Approx(1) ) is NOT correct!
  values: WARN( 50 == Approx( 1 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:482: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 1 == Approx( 50 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:483: WARNING: WARN( aspect == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -0.5 == Approx( 0.5 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:481: WARNING: WARN( znear == doctest::Approx(1) ) is NOT correct!
  values: WARN( 0.50505 == Approx( 1 ) )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:481: WARNING: WARN( znear == doctest::Approx(1) ) is NOT correct!
  values: WARN( 0.50505 == Approx( 1 ) )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:483: WARNING: WARN( aspect == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -0.5 == Approx( 0.5 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:481: WARNING: WARN( znear == doctest::Approx(1) ) is NOT correct!
  values: WARN( -1.04167 == Approx( 1 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:482: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 1 == Approx( 50 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:481: WARNING: WARN( znear == doctest::Approx(1) ) is NOT correct!
  values: WARN( -1.04167 == Approx( 1 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:482: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 1 == Approx( 50 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:483: WARNING: WARN( aspect == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -0.5 == Approx( 0.5 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:497: WARNING: WARN( aspect == doctest::Approx(1.3) ) is NOT correct!
  values: WARN( -1.3 == Approx( 1.3 ) )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:495: WARNING: WARN( znear == doctest::Approx(0.2) ) is NOT correct!
  values: WARN( 8 == Approx( 0.2 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:496: WARNING: WARN( zfar == doctest::Approx(8) ) is NOT correct!
  values: WARN( 0.2 == Approx( 8 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:495: WARNING: WARN( znear == doctest::Approx(0.2) ) is NOT correct!
  values: WARN( 8 == Approx( 0.2 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:496: WARNING: WARN( zfar == doctest::Approx(8) ) is NOT correct!
  values: WARN( 0.2 == Approx( 8 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:497: WARNING: WARN( aspect == doctest::Approx(1.3) ) is NOT correct!
  values: WARN( -1.3 == Approx( 1.3 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:495: WARNING: WARN( znear == doctest::Approx(0.2) ) is NOT correct!
  values: WARN( 0.101266 == Approx( 0.2 ) )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:495: WARNING: WARN( znear == doctest::Approx(0.2) ) is NOT correct!
  values: WARN( 0.101266 == Approx( 0.2 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:497: WARNING: WARN( aspect == doctest::Approx(1.3) ) is NOT correct!
  values: WARN( -1.3 == Approx( 1.3 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:495: WARNING: WARN( znear == doctest::Approx(0.2) ) is NOT correct!
  values: WARN( -0.210526 == Approx( 0.2 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:496: WARNING: WARN( zfar == doctest::Approx(8) ) is NOT correct!
  values: WARN( 0.2 == Approx( 8 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:495: WARNING: WARN( znear == doctest::Approx(0.2) ) is NOT correct!
  values: WARN( -0.210526 == Approx( 0.2 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:496: WARNING: WARN( zfar == doctest::Approx(8) ) is NOT correct!
  values: WARN( 0.2 == Approx( 8 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:497: WARNING: WARN( aspect == doctest::Approx(1.3) ) is NOT correct!
  values: WARN( -1.3 == Approx( 1.3 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:511: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:509: WARNING: WARN( znear == doctest::Approx(0.9) ) is NOT correct!
  values: WARN( 14 == Approx( 0.9 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:510: WARNING: WARN( zfar == doctest::Approx(14) ) is NOT correct!
  values: WARN( 0.9 == Approx( 14 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:509: WARNING: WARN( znear == doctest::Approx(0.9) ) is NOT correct!
  values: WARN( 14 == Approx( 0.9 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:510: WARNING: WARN( zfar == doctest::Approx(14) ) is NOT correct!
  values: WARN( 0.9 == Approx( 14 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:511: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:509: WARNING: WARN( znear == doctest::Approx(0.9) ) is NOT correct!
  values: WARN( 0.464945 == Approx( 0.9 ) )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:509: WARNING: WARN( znear == doctest::Approx(0.9) ) is NOT correct!
  values: WARN( 0.464945 == Approx( 0.9 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:511: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:509: WARNING: WARN( znear == doctest::Approx(0.9) ) is NOT correct!
  values: WARN( -1.03279 == Approx( 0.9 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:510: WARNING: WARN( zfar == doctest::Approx(14) ) is NOT correct!
  values: WARN( 0.9 == Approx( 14 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:509: WARNING: WARN( znear == doctest::Approx(0.9) ) is NOT correct!
  values: WARN( -1.03279 == Approx( 0.9 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:510: WARNING: WARN( zfar == doctest::Approx(14) ) is NOT correct!
  values: WARN( 0.9 == Approx( 14 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:511: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y reverse_z remap_z ]
===============================================================================
./tests/core/math/test_projection.h:516:
TEST CASE:  [Projection] Frustum values extraction

./tests/core/math/test_projection.h:527: WARNING: WARN( aspect == doctest::Approx(4.0 / 3.0) ) is NOT correct!
  values: WARN( -1.33333 == Approx( 1.33333 ) )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:525: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 49.9999 == Approx( 0.5 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:526: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 0.5 == Approx( 50 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:525: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 49.9999 == Approx( 0.5 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:526: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 0.5 == Approx( 50 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:527: WARNING: WARN( aspect == doctest::Approx(4.0 / 3.0) ) is NOT correct!
  values: WARN( -1.33333 == Approx( 1.33333 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:525: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 0.251256 == Approx( 0.5 ) )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:525: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 0.251256 == Approx( 0.5 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:527: WARNING: WARN( aspect == doctest::Approx(4.0 / 3.0) ) is NOT correct!
  values: WARN( -1.33333 == Approx( 1.33333 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:525: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -0.510204 == Approx( 0.5 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:526: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 0.5 == Approx( 50 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:525: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -0.510204 == Approx( 0.5 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:526: WARNING: WARN( zfar == doctest::Approx(50) ) is NOT correct!
  values: WARN( 0.5 == Approx( 50 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:527: WARNING: WARN( aspect == doctest::Approx(4.0 / 3.0) ) is NOT correct!
  values: WARN( -1.33333 == Approx( 1.33333 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:541: WARNING: WARN( aspect == doctest::Approx(1.5) ) is NOT correct!
  values: WARN( -1.5 == Approx( 1.5 ) )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:539: WARNING: WARN( znear == doctest::Approx(2) ) is NOT correct!
  values: WARN( 12 == Approx( 2 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:540: WARNING: WARN( zfar == doctest::Approx(12) ) is NOT correct!
  values: WARN( 2 == Approx( 12 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:539: WARNING: WARN( znear == doctest::Approx(2) ) is NOT correct!
  values: WARN( 12 == Approx( 2 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:540: WARNING: WARN( zfar == doctest::Approx(12) ) is NOT correct!
  values: WARN( 2 == Approx( 12 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:541: WARNING: WARN( aspect == doctest::Approx(1.5) ) is NOT correct!
  values: WARN( -1.5 == Approx( 1.5 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:539: WARNING: WARN( znear == doctest::Approx(2) ) is NOT correct!
  values: WARN( 1.09091 == Approx( 2 ) )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:539: WARNING: WARN( znear == doctest::Approx(2) ) is NOT correct!
  values: WARN( 1.09091 == Approx( 2 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:541: WARNING: WARN( aspect == doctest::Approx(1.5) ) is NOT correct!
  values: WARN( -1.5 == Approx( 1.5 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:539: WARNING: WARN( znear == doctest::Approx(2) ) is NOT correct!
  values: WARN( -3 == Approx( 2 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:540: WARNING: WARN( zfar == doctest::Approx(12) ) is NOT correct!
  values: WARN( 2 == Approx( 12 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:539: WARNING: WARN( znear == doctest::Approx(2) ) is NOT correct!
  values: WARN( -3 == Approx( 2 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:540: WARNING: WARN( zfar == doctest::Approx(12) ) is NOT correct!
  values: WARN( 2 == Approx( 12 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:541: WARNING: WARN( aspect == doctest::Approx(1.5) ) is NOT correct!
  values: WARN( -1.5 == Approx( 1.5 ) )
  logged: c := [ flip_y reverse_z remap_z ]
===============================================================================
./tests/core/math/test_projection.h:546:
TEST CASE:  [Projection] Orthographic values extraction

./tests/core/math/test_projection.h:556: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:554: WARNING: WARN( znear == doctest::Approx(1.2) ) is NOT correct!
  values: WARN( 15 == Approx( 1.2 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:555: WARNING: WARN( zfar == doctest::Approx(15) ) is NOT correct!
  values: WARN( 1.2 == Approx( 15 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:554: WARNING: WARN( znear == doctest::Approx(1.2) ) is NOT correct!
  values: WARN( 15 == Approx( 1.2 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:555: WARNING: WARN( zfar == doctest::Approx(15) ) is NOT correct!
  values: WARN( 1.2 == Approx( 15 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:556: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:554: WARNING: WARN( znear == doctest::Approx(1.2) ) is NOT correct!
  values: WARN( -12.6 == Approx( 1.2 ) )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:554: WARNING: WARN( znear == doctest::Approx(1.2) ) is NOT correct!
  values: WARN( -12.6 == Approx( 1.2 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:556: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:554: WARNING: WARN( znear == doctest::Approx(1.2) ) is NOT correct!
  values: WARN( 28.8 == Approx( 1.2 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:555: WARNING: WARN( zfar == doctest::Approx(15) ) is NOT correct!
  values: WARN( 1.2 == Approx( 15 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:554: WARNING: WARN( znear == doctest::Approx(1.2) ) is NOT correct!
  values: WARN( 28.8 == Approx( 1.2 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:555: WARNING: WARN( zfar == doctest::Approx(15) ) is NOT correct!
  values: WARN( 1.2 == Approx( 15 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:556: WARNING: WARN( aspect == doctest::Approx(2.5) ) is NOT correct!
  values: WARN( -2.5 == Approx( 2.5 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:568: WARNING: WARN( aspect == doctest::Approx(3) ) is NOT correct!
  values: WARN( -3 == Approx( 3 ) )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:566: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 6 == Approx( 0.5 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:567: WARNING: WARN( zfar == doctest::Approx(6) ) is NOT correct!
  values: WARN( 0.5 == Approx( 6 ) )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:566: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 6 == Approx( 0.5 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:567: WARNING: WARN( zfar == doctest::Approx(6) ) is NOT correct!
  values: WARN( 0.5 == Approx( 6 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:568: WARNING: WARN( aspect == doctest::Approx(3) ) is NOT correct!
  values: WARN( -3 == Approx( 3 ) )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:566: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -5 == Approx( 0.5 ) )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:566: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( -5 == Approx( 0.5 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:568: WARNING: WARN( aspect == doctest::Approx(3) ) is NOT correct!
  values: WARN( -3 == Approx( 3 ) )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:566: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 11.5 == Approx( 0.5 ) )
  logged: c := [ reverse_z remap_z ]

./tests/core/math/test_projection.h:567: WARNING: WARN( zfar == doctest::Approx(6) ) is NOT correct!
  values: WARN( 0.5 == Approx( 6 ) )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:566: WARNING: WARN( znear == doctest::Approx(0.5) ) is NOT correct!
  values: WARN( 11.5 == Approx( 0.5 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:567: WARNING: WARN( zfar == doctest::Approx(6) ) is NOT correct!
  values: WARN( 0.5 == Approx( 6 ) )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:568: WARNING: WARN( aspect == doctest::Approx(3) ) is NOT correct!
  values: WARN( -3 == Approx( 3 ) )
  logged: c := [ flip_y reverse_z remap_z ]
===============================================================================
./tests/core/math/test_projection.h:613:
TEST CASE:  [Projection] Perspective Half extents
./tests/core/math/test_projection.h:621: WARNING: WARN( ne.is_equal_approx(Vector2(1, 1) * 1) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:622: WARNING: WARN( fe.is_equal_approx(Vector2(1, 1) * 40) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y ]
./tests/core/math/test_projection.h:621: WARNING: WARN( ne.is_equal_approx(Vector2(1, 1) * 1) ) is NOT correct!
  values: WARN( false )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:622: WARNING: WARN( fe.is_equal_approx(Vector2(1, 1) * 40) ) is NOT correct!
  values: WARN( false )
  logged: c := [ reverse_z ]

./tests/core/math/test_projection.h:621: WARNING: WARN( ne.is_equal_approx(Vector2(1, 1) * 1) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z ]

./tests/core/math/test_projection.h:622: WARNING: WARN( fe.is_equal_approx(Vector2(1, 1) * 40) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z ]

./tests/core/math/test_projection.h:621: WARNING: WARN( ne.is_equal_approx(Vector2(1, 1) * 1) ) is NOT correct!
  values: WARN( false )
  logged: c := [ remap_z ]

./tests/core/math/test_projection.h:621: WARNING: WARN( ne.is_equal_approx(Vector2(1, 1) * 1) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:622: WARNING: WARN( fe.is_equal_approx(Vector2(1, 1) * 40) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:621: WARNING: WARN( ne.is_equal_approx(Vector2(1, 1) * 1) ) is NOT correct!
  values: WARN( false )
  logged: c := [ reverse_z remap_z ]

./tests/core/math/test_projection.h:622: WARNING: WARN( fe.is_equal_approx(Vector2(1, 1) * 40) ) is NOT correct!
  values: WARN( false )
  logged: c := [ reverse_z remap_z ]

./tests/core/math/test_projection.h:621: WARNING: WARN( ne.is_equal_approx(Vector2(1, 1) * 1) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z remap_z ]

./tests/core/math/test_projection.h:622: WARNING: WARN( fe.is_equal_approx(Vector2(1, 1) * 40) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z remap_z ]

===============================================================================
./tests/core/math/test_projection.h:644:
TEST CASE:  [Projection] Orthographic Half extents

./tests/core/math/test_projection.h:651: WARNING: WARN( ne.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y ]

./tests/core/math/test_projection.h:652: WARNING: WARN( fe.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y ]

./tests/core/math/test_projection.h:651: WARNING: WARN( ne.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z ]

./tests/core/math/test_projection.h:652: WARNING: WARN( fe.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z ]

./tests/core/math/test_projection.h:651: WARNING: WARN( ne.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:652: WARNING: WARN( fe.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:651: WARNING: WARN( ne.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:652: WARNING: WARN( fe.is_equal_approx(Vector2(3, 1.5)) ) is NOT correct!
  values: WARN( false )
  logged: c := [ flip_y reverse_z remap_z ]
===============================================================================
./tests/core/math/test_projection.h:746:
TEST CASE:  [Projection] Pixels per meter

./tests/core/math/test_projection.h:753: WARNING: WARN( ppm == int(1536.0f / sqrt3) ) is NOT correct!
  values: WARN( 22 == 886 )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:753: WARNING: WARN( ppm == int(1536.0f / sqrt3) ) is NOT correct!
  values: WARN( 22 == 886 )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:753: WARNING: WARN( ppm == int(1536.0f / sqrt3) ) is NOT correct!
  values: WARN( 1751 == 886 )
  logged: c := [ remap_z ]
./tests/core/math/test_projection.h:753: WARNING: WARN( ppm == int(1536.0f / sqrt3) ) is NOT correct!
  values: WARN( 1751 == 886 )
  logged: c := [ flip_y remap_z ]
./tests/core/math/test_projection.h:753: WARNING: WARN( ppm == int(1536.0f / sqrt3) ) is NOT correct!
  values: WARN( -842 == 886 )
  logged: c := [ reverse_z remap_z ]
./tests/core/math/test_projection.h:753: WARNING: WARN( ppm == int(1536.0f / sqrt3) ) is NOT correct!
  values: WARN( -842 == 886 )
  logged: c := [ flip_y reverse_z remap_z ]
./tests/core/math/test_projection.h:759: WARNING: WARN( ppm == int(800.0f / sqrt3) ) is NOT correct!
  values: WARN( 11 == 461 )
  logged: c := [ reverse_z ]
./tests/core/math/test_projection.h:759: WARNING: WARN( ppm == int(800.0f / sqrt3) ) is NOT correct!
  values: WARN( 11 == 461 )
  logged: c := [ flip_y reverse_z ]
./tests/core/math/test_projection.h:759: WARNING: WARN( ppm == int(800.0f / sqrt3) ) is NOT correct!
  values: WARN( 912 == 461 )
  logged: c := [ remap_z ]

./tests/core/math/test_projection.h:759: WARNING: WARN( ppm == int(800.0f / sqrt3) ) is NOT correct!
  values: WARN( 912 == 461 )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:759: WARNING: WARN( ppm == int(800.0f / sqrt3) ) is NOT correct!
  values: WARN( -438 == 461 )
  logged: c := [ reverse_z remap_z ]

./tests/core/math/test_projection.h:759: WARNING: WARN( ppm == int(800.0f / sqrt3) ) is NOT correct!
  values: WARN( -438 == 461 )
  logged: c := [ flip_y reverse_z remap_z ]

./tests/core/math/test_projection.h:777: WARNING: WARN( ppm == 1536 ) is NOT correct!
  values: WARN( 15 == 1536 )
  logged: c := [ reverse_z ]

./tests/core/math/test_projection.h:777: WARNING: WARN( ppm == 1536 ) is NOT correct!
  values: WARN( 15 == 1536 )
  logged: c := [ flip_y reverse_z ]

./tests/core/math/test_projection.h:777: WARNING: WARN( ppm == 1536 ) is NOT correct!
  values: WARN( 3056 == 1536 )
  logged: c := [ remap_z ]

./tests/core/math/test_projection.h:777: WARNING: WARN( ppm == 1536 ) is NOT correct!
  values: WARN( 3056 == 1536 )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:777: WARNING: WARN( ppm == 1536 ) is NOT correct!
  values: WARN( -1505 == 1536 )
  logged: c := [ reverse_z remap_z ]

./tests/core/math/test_projection.h:777: WARNING: WARN( ppm == 1536 ) is NOT correct!
  values: WARN( -1505 == 1536 )
  logged: c := [ flip_y reverse_z remap_z ]

./tests/core/math/test_projection.h:783: WARNING: WARN( ppm == 400 ) is NOT correct!
  values: WARN( 39 == 400 )
  logged: c := [ reverse_z ]

./tests/core/math/test_projection.h:783: WARNING: WARN( ppm == 400 ) is NOT correct!
  values: WARN( 39 == 400 )
  logged: c := [ flip_y reverse_z ]

./tests/core/math/test_projection.h:783: WARNING: WARN( ppm == 400 ) is NOT correct!
  values: WARN( 760 == 400 )
  logged: c := [ remap_z ]

./tests/core/math/test_projection.h:783: WARNING: WARN( ppm == 400 ) is NOT correct!
  values: WARN( 760 == 400 )
  logged: c := [ flip_y remap_z ]

./tests/core/math/test_projection.h:783: WARNING: WARN( ppm == 400 ) is NOT correct!
  values: WARN( -320 == 400 )
  logged: c := [ reverse_z remap_z ]

./tests/core/math/test_projection.h:783: WARNING: WARN( ppm == 400 ) is NOT correct!
  values: WARN( -320 == 400 )
  logged: c := [ flip_y reverse_z remap_z ]
===============================================================================
[doctest] test cases:  31 |  31 passed | 0 failed | 1211 skipped
[doctest] assertions: 206 | 206 passed | 0 failed |
[doctest] Status: SUCCESS!
Process 71182 exited with status = 0 (0x00000000)

@Flarkk Flarkk force-pushed the fix_corrected_projection branch from ddffe0d to 27cadb6 Compare July 4, 2025 13:41
@clayjohn
Copy link
Member

clayjohn commented Jul 4, 2025

I wonder if an easier solution would be preferable. Personally, I am unhappy that we have exposed the transformed projection directly, we should have exposed it as an array of floats or something to make it clear that it is just for passing to the GPU.

Therefore, I would suggest the following:

  1. Add a new function RenderSceneData.get_transformed_projection_data() which returns a PackedFloatArray with the projection data.
  2. Add a WARN_PRINT_ONCE() to RenderSceneData.get_cam_projection that says it is the transformed projection and is only suitable for copying to the GPU and that the user should use RenderSceneData.get_transformed_projection_data() instead.

The goal with this approach is to discourage users from using the getters at all. If needed, we can expose z_far and z_near directly through RenderSceneData since it stores those values anyway

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants