-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Suggestion of a function to get screen coordinates #7059
Comments
I think this could make sense to add, anecdotally it's probably the question I've been asked the most about p5, although not exclusively to WebGL, so 2D mode could feasibly implement something like this too. @limzykenneth any thoughts on naming? Flash used to have methods like (Also, I reopened the issue, was it intended to be closed?) |
FYI - I brought up this issue with @bohnacker years ago (while attempting to port a Processing lib to p5.js that depended on screenX/Y/Z) and they came up with the following solution (I'm not sure if it's been submitted for the upcoming new website (of which all existing ones should be auto-ported incase authors didn't see message to submit) – would of course be great to have them built in! |
After I came up with the idea, I lost motivation, so I closed it. |
I too agree to this , it would be nice to have such a function. |
Having a function like this will help contributors create new methods, like I did in #6116. I also think it is useful because it can be used to place visual information in 3D space. 2024-06-03.21-46-57.mp4 |
For reference, two additional issue threads that dove into this topic: |
I like worldToScreen, it also leaves open a possibility of screenToWorld in the future too. |
I didn't understand the demo referenced above by @inaridarkfox4231 which had a sphere with lighting changing, but upon digging into your sketches, found a very relevant and well working example: ndc4_depthValue by dark_fox - amazing snippet! +1 for |
One small thing to add – Processing's |
In the sketch introduced in the comment above, validation is applied using the depth value so that it is not displayed if it is on the back side. // Validate using the depth value of the origin
const ndc0 = getNDC(createVector(0,0,0));
for(let i=0; i<12; i++){
const v = icosaV[i];
const ndc = getNDC(v);
if(ndc.z>ndc0.z)continue;
if(showType===0)guide.text(vertexDataIcosa[i], ndc.x, ndc.y);
if(showType===1)guide.text("["+i+"]",ndc.x, ndc.y);
} (After that, I made various changes for that sketch, and removed the ball because it was unnecessary.) |
I left some code for world to local over here in a comment a while ago: https://www.reddit.com/r/p5js/s/6co56yZ78u The reverse, local to screen, would be something like: const matrix = drawingContext.getTransform();
const localCoord = matrix
.scale(1 / pixelDensity())
.transformPoint(
new DOMPoint(x, y)
); |
@davepagurek Wow that's awesome! For whatever/obvious reason the const matrix = drawingContext.getTransform();
let pd = pixelDensity();
let scl = 1 / pd;
let transform = createVector(0, 0);
if(pd != 1){
transform = createVector(-width * scl, -height * scl);
}
return matrix
.scale(scl)
.translate(transform.x, transform.y)
.transformPoint(
new DOMPoint(v.x, v.y)
); |
Oops, my fault, I think that's an order of operations problem. So p5 deals with pixel density by applying an initial Here's a sketch that I think should work: function setup() {
createCanvas(200, 200)
pixelDensity(3)
translate(width/2, height/2)
const matrix = new DOMMatrix()
.scale(1 / pixelDensity())
.multiply(drawingContext.getTransform());
console.log(matrix
.transformPoint(
new DOMPoint(0, 0)
));
// Logs 100, 100
} |
@davepagurek This all goes wooosh over my head, but very interesting to follow and worked perfect for all big/tiny densities, thanks for having another look at it. Here's my implementation for a library I'm in early stages of sketching, where it's great to 'flatten' any transformed points in 2D/3D space and this combined with @inaridarkfox4231 example for WEBGL work amazingly, so many thanks for figuring out these complex issues! Already flagged to do so, and hope this finds its way into v2.0, since it's something I've wished for many times in the past (having been so used to it from Processing world). I think across the various issues on the topic, there have been multiple folks interested to jump in for a contribution. Here's a basic combination of both – of course a fully fledged out implementation would also need to take into account function screenVector(v) {
if(_renderer.drawingContext instanceof CanvasRenderingContext2D) {
const matrix = new DOMMatrix()
.scale(1 / pixelDensity())
.multiply(drawingContext.getTransform());
return matrix
.transformPoint(
new DOMPoint(v.x, v.y)
);
} else {
const _gl = _renderer;
const camCoord = _gl.uMVMatrix.multiplyPoint(v);
const ndc = _gl.uPMatrix.multiplyAndNormalizePoint(camCoord);
const _x = (0.5 + 0.5 * ndc.x) * width;
const _y = (0.5 - 0.5 * ndc.y) * height;
const _z = (0.5 + 0.5 * ndc.z);
return createVector(_x, _y, _z);
}
} |
Increasing access
Proposal to implement functions like screenX(), screenY(), screenZ() in processing.
I often see suggestions that p5.js also needs a function to calculate screen coordinates.
I thought it would be good to have such a function, even if it's not the method I proposed here.
Most appropriate sub-area of p5.js?
Feature request details
I thought of a function like this:
This is a function that calculates screen coordinates and depth values from 3D coordinates for the currently set camera.
Screen coordinates are values based on the coordinate system of the 2D canvas, and depth values are 0 for near and 1 for far.
This kind of technique is actually already used in the p5.js library.
In #6116, when I improved orbitControl, it became necessary to obtain normalized device coordinates, so I implemented functions by suggestion of dave pagurek.
The method used here is based on that method.
"getNDC" is a temporary name and has no particular meaning. I think it needs to be changed with a proper name.
getNDC demo
2024-05-19.09-02-24.mp4
The text was updated successfully, but these errors were encountered: