# get screen position using mvp matrix in script

hi

iโm studying about projection matrix. i think mvp * localModel position is screen position

but when i try below code it display difference result.

what am i wrong?

can anyone explain this would be thankful.

Matrix4x4 m = transform.localToWorldMatrix;
Matrix4x4 v = Camera.mainCamera.worldToCameraMatrix;
Matrix4x4 p = Camera.mainCamera.projectionMatrix;

Matrix4x4 MVP = pvm;

Mesh mesh = gameObject.GetComponent().mesh;
Vector3[ ] vertices = mesh.vertices;

int i = 0;
while (i < vertices.Length) {

print(MVP.MultiplyPoint(vertices*)); // โ i expect this result same as WorldToScreenPoint but itโs not!*
_ print(Camera.mainCamera.projectionMatrix.MultiplyPoint(vertices*));_
_ print(Camera.mainCamera.WorldToScreenPoint(vertices));
i++;
}*_

try mvp

Vectors are right-multiplied with transformation matrices, so PVM*vertex is correct.

Astrokoo, have you looked at this question?

After vertex transformed by mvp, it is in clip space ,not in screen space,either(-1,1) nor (screen.width,screen.height)

Yes, this is an important observation too. MVP takes a vertex from object space to clip space, whose (x, y) coordinates are in (-1, 1). Rasterization to screen space in a shader is a hidden step between your vertex and fragment programs. You will have to scale and bias the resulting value if you want to get to screen space ((0, 0), (Screen.width, height)), or viewport space (0, 1).

1 Like

I have same problem.

why MVP.MultiplyPoint(vertices*) is not same as WorldToScreenPoint?*

You should use this:

Matrix4x4 matrix = _3dCamera.projectionMatrix * _3dCamera.worldToCameraMatrix;
Vector3 screenPos = matrix.MultiplyPoint(newObj.transform.position);

// (-1, 1)'s clip => (0 ,1)'s viewport
screenPos= new Vector3(screenPos.x + 1f, screenPos.y + 1f, screenPos.z + 1f) / 2f;

// viewport => screen
screenPos = new Vector3(screenPos.x * Screen.width, screenPos.y * Screen.height, screenPos.z);

1 Like