Description
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?
- Accessibility
- Color
- Core/Environment/Rendering
- Data
- DOM
- Events
- Image
- IO
- Math
- Typography
- Utilities
- WebGL
- Build process
- Unit testing
- Internationalization
- Friendly errors
- Other (specify if possible)
Feature request details
I thought of a function like this:
p5.prototype.getNDC = function (v){
const _gl = this._renderer;
// Transfer to camera coordinate system using uMVMatrix
const camCoord = _gl.uMVMatrix.multiplyPoint(v);
// Calculate ndc using uPMatrix
const ndc = _gl.uPMatrix.multiplyAndNormalizePoint(camCoord);
// Drop into canvas coordinates.
// The depth value is converted so that near is 0 and far is 1.
const _x = (0.5 + 0.5 * ndc.x) * this.width;
const _y = (0.5 - 0.5 * ndc.y) * this.height;
const _z = (0.5 + 0.5 * ndc.z);
// Output in vector form.
return createVector(_x, _y, _z);
}
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.
let gr;
function setup() {
createCanvas(400, 400, WEBGL);
gr = createGraphics(400, 400);
gr.textSize(20);
gr.textAlign(CENTER,CENTER);
noStroke();
}
function draw() {
background(220);
orbitControl();
lights();
fill(255);
sphere(40);
const ndc = getNDC(createVector(0,0,0));
gr.clear();
gr.text(ndc.z.toFixed(2), ndc.x, ndc.y);
push();
noLights();
camera(0,0,1,0,0,0,0,1,0);
ortho(-1,1,-1,1,0,1);
translate(0,0,1);
texture(gr);
plane(2);
pop();
}
p5.prototype.getNDC = function (v){
const _gl = this._renderer;
// Transfer to camera coordinate system using uMVMatrix
const camCoord = _gl.uMVMatrix.multiplyPoint(v);
// Calculate ndc using uPMatrix
const ndc = _gl.uPMatrix.multiplyAndNormalizePoint(camCoord);
// Drop into canvas coordinates.
// The depth value is converted so that near is 0 and far is 1.
const _x = (0.5 + 0.5 * ndc.x) * this.width;
const _y = (0.5 - 0.5 * ndc.y) * this.height;
const _z = (0.5 + 0.5 * ndc.z);
// Output in vector form.
return createVector(_x, _y, _z);
}
2024-05-19.09-02-24.mp4
Metadata
Metadata
Assignees
Type
Projects
Status
Status