Reputation: 152
I've developed an iOS app that Metal renders a 2D image with a depth map into 3D using perspective projection. The rendering works well, but I'm trying to determine the final screen position of a point from the original 2D image.
For testing, I'm using a point at (0, 0) with zero depth. My getMapTexturePoint() function returns the mapped point (-0.53, 0.33125) for a texture size of 512x320.
Here's my code for calculating the final screen position:
// map texture position from screen point (x,y)
let mappedPoint = getMapTexturePoint(x: point.x, y: point.y)
// set mappedPoint as a 4D point, depth(z) is setting to 0
let localPoint = SIMD4<Float>(mappedPoint.x, mappedPoint.y, 0, 1)
// count clipSpacePoint using model-view-projection matrix
let clipSpacePoint = projectionMatrix * viewMatrix * modelMatrix * localPoint
// perspective division
let ndcPoint = clipSpacePoint / clipSpacePoint.w
// Count the point on the final position on the screen
let screenPoint = SIMD2<Float>((ndcPoint.x + 1) * 0.5 * screenWidth,
(1 - ndcPoint.y) * 0.5 * screenHeight)
// model matrix:
simd_float4x4([[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0]])
// view matrix:
simd_float4x4([[0.9994884, -0.0, 0.031983633, 0.0],
[0.0, 1.0, 0.0, 0.0],
[-0.031983633, 0.0, 0.9994884, 0.0],
[0.031983633, -0.0, 0.0010234762, 1.0]])
// projection matrix:
simd_float4x4([[1.2062852, 0.0, 0.0, 0.0],
[0.0, 2.1445072, 0.0, 0.0],
[0.0, 0.0, 1.001001, 1.0],
[0.0, 0.0, -0.1001001,0.0]])
I got result as:
clipSpacePoint: (-0.6004227, 0.710368, -0.116043895, -0.015927847)
ndcPoint: (37.69641, -44.59912, 7.2855983, 1.0)
screenPoint: (27861.416, 20519.605)
Are my steps correct, or am I missing something? I want to ensure I'm accurately projecting the original 2D point to its final screen position.
Upvotes: 0
Views: 24