-
Notifications
You must be signed in to change notification settings - Fork 350
Adjust CPU isTouchingColor to match GPU results #407
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
Adjust CPU isTouchingColor to match GPU results #407
Conversation
For some reason the JavaScript engine insists on running the code instead of doing what the comment says. I guess they should match.
Math.floor(vec[1] * (this._height - 1)), | ||
dst | ||
); | ||
const x = Math.round(vec[0] * this._width); |
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.
I went back and forth a long time on if -1 was needed here or not -- do you have some ninja unit/integration testing that proves it isn't?
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.
I was using #406 extensively while working on this, and skipping the -1 here is one of the main changes that makes the results exactly the same as the GPU version. In fact, this work is why I did #406 in the first place :)
I also drew it out on paper to convince myself that it's correct: take a look at which texel you "want" to sample in a 4-texel-wide image when your texture coordinate is 0.01, 0.24, 0.26, 0.49, 0.51, 0.74, 0.76, and 0.99.
src/RenderWebGL.js
Outdated
) { | ||
return true; | ||
for (let x = 0; x < bounds.width; ++x) { | ||
point[1] = bounds.top - y; // bounds.top <= y < bounds.bottom ("flipped") |
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.
I really don't like the fact that this ends up with y !== point[1]
-- can we maybe rename the outer loop var to yFromTop
or something
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.
Hmm, I kind of agree but on the other hand if you combine this with #406 then you end up with debugCanvasContext.fillRect(x, y, 1, 1)
being the correct way to draw to the debug canvas to match the GPU path's results. I'm not saying that clean debug code should be the priority (ha!) but rather I feel like that's a sign that these are the "natural" values for x
and y
. (Side note: it's very satisfying to see the CPU path early-out when a matching color is found, leaving the rest of the canvas blank!)
Consider also that 0 <= y < bounds.height
and 0 <= x < bounds.width
are both correct here, as is bounds.left <= point[0] < bounds.right
, but bounds.bottom <= point[1] < bounds.top
is wrong.
Actually, that makes me realize that this comment refers to the wrong variable. I'll fix that :/
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.
Awesome work Chris! - thanks for cleaning up a bunch of my typos in comments too :)
Resolves
Fixes some causes of #214
Proposed Changes
Functionality changes:
isTouchingColor
to avoid testing extra edge pixelscolorAtNearest
to match hardware texture sampling resultssampleColor4b
no longer contains an early-out bounds test sincecolorAtNearest
does the same test more accurately. For example, we were previously getting incorrect results when "zero" turned into a very small negative number due to floating point error.Other changes:
Reason for Changes
The CPU version of
isTouchingColor
,sampleColor4b
, and a few related functions were not returning the same results as their GPU equivalents. This could cause unexpected behavior, especially if a project uses both paths.Test Coverage
See #406