-
Notifications
You must be signed in to change notification settings - Fork 102
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
Fix perspective projection transform #465
base: main
Are you sure you want to change the base?
Conversation
Please review this commit carefully, as I only partially know what I'm doing. I believe that setting `m44` to one for the perspective projection matrix is wrong. First, the sources I can find that explain this all set it to zero. Granted, I can't find many sources online that explain this clearly, but the few that I can find support my point (see Wikipedia[1] and this university lecture[2], for example). Second, I did some transformation on paper, to better understand this, and while the approaches in the cited sources starting making sense to me, I can't make head or tails of that one in the m44 position. It just seems to get in the way. So while I can't rule out that the way things currently are make total sense for reasons I don't understand yet, as of right now, it seems more like an oversight. [1] https://en.wikipedia.org/wiki/Transformation_matrix#Perspective_projection [2] https://courses.cs.washington.edu/courses/cse455/09wi/Lects/lect5.pdf, page 23
You had me scratch my head for a good hour and a half (and I learned stuff in the process). Before we go into why, let's start with references (it at least gave me some confidence that we aren't doing something crazy)
Why then ? It's interesting because your reasoning and your sources do make sense. My understanding is that it is a question of which plane the perspective transform is projecting things on. In the case of euclid, the matrix projects points onto the plane defined by I think that it makes most sense for euclid to keep perspective as is and continue following the CSS specification. That said this method really need better documentation. Anyway I'll close this now since I believe that we shouldn't change the behavior of perspective. |
Improve the documentation of Transform3D::perspective There was a bit of confusion about the formulation of the perspective transform in #465. This clarifies things.
Thank you for your reply! I hate to take up more of your time, but here I go.
Those are certainly some strong sources. If I had been aware of those at an earlier point, I probably wouldn't have even posted this pull request. However, I'm too deep into it by now to just yield to these, especially since I don't quite follow your explanation :-)
I think this isn't quite on point, for two reasons. First, yes, the Wikipedia matrix projects to Second, I don't believe that projecting to First, let's take a closer look at the matrices. I'm going to ignore the Wikipedia matrix from here on, as it's basically equivalent to the Washington matrix (modulo the hardcoded distance and different viewing direction), and the Washington matrix is much closer to the Euclid one, hence being better suited to demonstrate the difference. Here's the Washington matrix:
And here's the Euclid matrix. Please note that the Euclid documentation formats matrices differently, based on the order of their fields in memory. I'm translating it into the format used by all of the sources (including yours) here, for clarity:
The only difference between them is the I'm claiming that the Washington matrix projects points into the Let's try that for the Washington matrix with
We're getting the same point out that we put in. Let's do the same with the Euclid matrix:
The
Which are not the same coordinates that our original point had, even though we were projecting it into the plane it was already in. Doing the same for other planes leads to similar results. I've done lots more calculations along the same lines, and the result is always the same: The Washington approach (with Maybe I'm missing something. Maybe the Euclid approach has some advantage that I'm not seeing. Maybe something else needs to happen before or after the perspective transformation to correct for this (I don't know what that might be, or why it might be an advantage). Thoughts on your sourcesIf this was just a Euclid thing, I'd be fully convinced that this is buggy behavior that needs to change. However, that you can point to those sources that are doing it the same way, is a strong argument that there is something going on here that I don't understand. I don't have much insight into browser and web standards development, so what I'm about to say might be preposterous. Still, let me float this possibility: Is it possible, that this is an error in the spec, and everyone just copied the same mistake from the spec and/or each other? Please consider the following notes, that could make this theory less preposterous:
Again, this might be preposterous, as I don't know how much scrutiny goes into the development of these standards and their implementation. Additional sourcesWhile articles explaining this subject clearly (and without resorting to "call this perspective function to make the matrix") seem to be rare, all I have seen use a I figured it wouldn't hurt to dig up some more sources, preferably involving real code. Here's what I came up with:
I didn't omit any sources. I just looked up the math libraries I could come up with off the top of my head, and all of them set I'm sorry for being so persistent when it's so likely I'm just missing something, but I've become obsessed at this point. If the behavior in Euclid is correct, I absolutely need to know why :-) |
I'm going to have to ponder on this for a bit, don't worry if you don't hear back for a time. @jrmuizel do you have any insight or know who was involved in this spec? |
my two cents on this(after discussed with @lezzokafka):
|
Thank you for your comment, @yihuang. I have some notes on what you wrote.
As far as I know, it is convention to always set I think your comment, that the matrix is correct if
Again, I think this is true, but I wonder if it is a real use case. Setting a (positive) Interesting points, definitely, but I'd be interested if anyone can point to examples that use the perspective matrix in such a way that makes |
"correct" here is mostly a matter of against what specification. What I'd like to figure out is a proper way to explain what this does (and why as a bonus point). It's too late for web specs to change in any case even in the eventuality that another formulation of perspective transforms would have been a better choice. We need in euclid a perspective method that follows the web specification. If we can't reconcile the current implementation with something universally useful, we'll probably rename |
In an earlier comment, you claimed that the Out of all the sources mentioned, the only counterpoint to this interpretation is the CSS Transforms spec and the browsers that follow it. So far, no-one has offered an explanation of what the intention behind this divergence is, nor any evidence that it isn't a simple mistake in the spec.
That the web spec can't be changed, even if this turns out to be a straight mistake, certainly paints a depressing picture, and makes me glad I'm not involved in this world :-) But as far as Euclid is concerned, I'd be fine with that outcome. I'd like to offer one note though: If a buggy perspective matrix is required (if this turns out to indeed be a bug), it is quite easy to adjust a correct (as per the definition I proposed above) matrix as required ( From my subjective perspective as a non-web user of Euclid, a library that mentions nowhere in its documentation that it is specific to the web or browsers, such a workaround at the use site would be slightly better than a weird method doing the wrong thing (if indeed it turns out to be wrong). |
Yeah, my bad, I was trying to piece this mess together and apparently took a wrong shortcut. I'm hopeful that we'll be able to better understand this stuff, though. It's a busy time at mozilla right now, there's only so much of it I can spend figuring this out. Euclid isn't meant to be web-specific but the people who write most of it do web things so it at least needs to meet that use case (no reason we can't add other things that are universally useful).
Glad I can contribute to you knowing how lucky you are :)
I shouldn't have nitpicked about the word "correct". But again, whatever the outcome of this investigation, best to think about it as a transform that looks like a perspective, quacks like a perspective, actually is a perspective, and is available for use if you need some compatibility with how things look in a browser or webview. The perspective isn't wrong or buggy per se (granted, the doc is). There are many perspective projections and this one, even if not the one you want to use has reasons to exist, if only because it is used by a whole ecosystem of apps by now (for better or worse and before we decide which one it is we have to figure out why). |
I didn't mean to call you out for that, and I'm sorry if it came across that way. I merely meant to reference that statement, to support my case for what a reasonable definition of correctness is.
I totally understand, and there's no hurry from my side. I too hope we'll be able to clear this up, either by confirming my suspicions about the spec, or by figuring out where I'm wrong or what I'm missing.
I actually used to be a web developer many years ago. I grew frustrated by living on top of this huge behemoth (the browser) that I could not understand, much less control, and I decided to switch to embedded development. These days I struggle with buggy hardware that has user manuals with hundreds or thousands of pages I need to understand, but still manages to be under-documented :-) Still, I'm happy about my decision. And these days, when I do web development, it's a lot more fun (not having decisions about browser support, design, and choice of technology dictated by a client does wonders in that regard).
Yeah, as I said, I'd be fine with the outcome you described. I just wanted to offer my perspective, but I understand that life is full of trade-offs. |
Please review this commit carefully, as I only partially know what I'm
doing. I believe that setting
m44
to one for the perspectiveprojection matrix is wrong.
First, the sources I can find that explain this all set it to zero.
Granted, I can't find many sources online that explain this clearly, but
the few that I can find support my point (see Wikipedia[1] and this
university lecture[2], for example).
Second, I did some transformation on paper, to better understand this,
and while the approaches in the cited sources starting making sense to
me, I can't make head or tails of that one in the m44 position. It just
seems to get in the way.
So while I can't rule out that the way things currently are make total
sense for reasons I don't understand yet, as of right now, it seems more
like an oversight.
[1] https://en.wikipedia.org/wiki/Transformation_matrix#Perspective_projection
[2]
https://courses.cs.washington.edu/courses/cse455/09wi/Lects/lect5.pdf,
page 23