How do I use WorldToViewportPoint() and ViewportToWorldPoint() on separate thread?
I am writing a script that works on a massive amount of particles, so I needed to implement multithreading. Everything works, except that whenever I call WorldToViewportPoint() on the main camera I get: "INTERNAL_CALL_WorldToViewportPoint can only be called from the main thread", and the same happens when I try to use ViewportToWorldPoint().
So I'm kind of stuck. How can I emulate the functions using my own thread-safe implementation? I'm sure it's possible, even if some values have to be hardcoded.
Answer by LucaHofmann · Dec 03, 2017 at 12:42 PM
Let's assume you want to convert the transform.position to screen coordinates: screenSpace is what you want:
Matrix4x4 world2Screen = Camera.main.projectionMatrix * Camera.main.worldToCameraMatrix;
Matrix4x4 screen2World = world2Screen.inverse;
Vector3 screenSpace = world2Screen.MultiplyPoint(transform.position);
Vector3 worldSpace = screen2World.MultiplyPoint(screenSpace);
The last line is to convert screen coordinates to world space. In this example converting it back makes no sense.. it is just to show how it works and to check if it's right :)
Answer by BarShiftGames · Sep 27, 2020 at 01:20 AM
Just testing it out, @LucaHofmann your answer does NOT provide the same result as worldToViewportPoint, and I verified it on the same set of coordinates and got different outputs, even if I used multiplypoint3x4
For future purposes, the correct code looks like this, but I have forgotten where I got it from, and this is only screen to worldToViewportPoint, I forget what you would do to invert this process. Coding format on this website doesn't work for me ever, so I have no idea what this will look like when I paste it. You can pull out bits and pieces to multithread, like pre-calculating the m4 matrix, since you can't pass camera references through threads.
$$anonymous$$atrix4x4 m4 = cameraReference.projection$$anonymous$$atrix * cameraReference.transform.worldToLocal$$anonymous$$atrix;
Vector4 p4 = <input vector3 point here>;
p4.w = 1;
Vector4 result4 = m4 * p4;
Vector3 result = result4;
result /= -result4.w;
result.x = result.x / 2 + 0.5f;
result.y = result.y / 2 + 0.5f;
result.z = -result4.w;