-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify and fix Projection
's getter functions
#100209
base: master
Are you sure you want to change the base?
Conversation
3c82199
to
cee7e82
Compare
Replaced |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is very interesting to me, considering it could eliminate a large number of computations in the rendering pipeline.
However, I'm also a bit concerned about the reduction in complexity. I think you're making a few assumptions that may not be true in nonstandard setups.
May I ask, how did you arrive at the simplifications in this PR?
core/math/projection.cpp
Outdated
new_plane.normalize(); | ||
|
||
return new_plane.d; | ||
return -(columns[3][3] - columns[3][2]) / (columns[2][2] - columns[2][3]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as an example, I think this would yield incorrect values for non-perspective projection matrices (e.g. orthographic).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The far plane's homogeneous coordinate (Vector4
) is row[3] - row[2] (see previous implementation).
Zfar is the intercept of the plane, namely its w
component after normalization.
I'm making one assumption here that is the far plane is perpendicular to Z (i.e. both x
and y
equal 0 in the above vector) which is the case in all current projection modes1.
Under those conditions, normalizing the plane is just doing w / abs(z)
, which is exacty what's done in the new implementation.
I made sure all unit tests still pass (and added new ones to cover all projection modes).
Of course it's not a guarantee that the code is bug free, but I'm pretty confident on this one.
If you can add more tests to cover the edge cases you may have in mind, please do.
Footnotes
-
x
andy
may not be 0 anymore once we introduce oblique clipping planes. A specific code path might be needed then to perform a full normalization. That being said, Zfar kind of looses all its meaning with oblique planes, so I'm not even sure it would be relevant at all. ↩
Sure thing. Here we are : AssumptionsThere are 3 general assumptions, and only really 1 new :
All 3 are always true with our current projection modes (ORTHOGONAL, PERSPECTIVE, FRUSTUM). Rationale
|
Awesome, thank you for the detailed breakdown! I do have one request: Please document assumptions you make (or alternatively, those you specifically do not make) in the respective functions. It's a bit of an unfair ask, since they haven't been documented so far, but I think it's essential to keep the code integrity intact for maintainers and future contributors. Here's a rough example of what I mean: real_t Projection::get_z_far() const {
// NOTE: This assumes that:
// - The far plane is a rectangle orthogonal to z (incorrect for oblique clipping planes, which are not supported).
// - The matrix is a valid projection matrix.
return -(columns[3][3] - columns[3][2]) / (columns[2][2] - columns[2][3]);
} This might be a bit verbose, based on the overarching assumptions of the |
cee7e82
to
452c66d
Compare
@Ivorforce just took a stab at it - see my last push.
|
Awesome!! This es exactly what I was looking for. |
Fixes #90427
Fixes #93683
This PR simplifies and fixes a few functions of struct
Projection
:get_aspect()
andget_lod_multiplier()
with camera in `PROJECTION_FRUSTUM mode. The latter now has a uniform behavior no matter the camera mode (perspective, frustum and orthographic). Besides it was broken in frustum mode, it also used to decimate meshes twice slower in orthographic than in perspective mode.get_pixels_per_meter()
. Note : this function has a clumsy definition and is not used anywhere. It's a good candidate for deprecation.get_z_far()
,get_z_near()
,get_viewport_half_extents()
,get_far_plane_half_extents()
andget_fov()
Test project for LOD multiplier issues : lod.zip