# Question Camera distortion Post-Processing & ScreenPointToRay

Discussion in 'General Graphics' started by pablobandinopla, Aug 7, 2023.

1. ### pablobandinopla

Joined:
Jul 2, 2021
Posts:
97
When using camera distortion volume effects calling ScreenPointToRay returns values without taking into acconut the distorted viewport...

is there a way to solve this? for example a way to apply the visual distortion to the coordinates too?
For example the Lens Distorion volume, hen set to high disortion values, it makes ScreenPointToRay useless... it would be cool if one could get the Input.mousePosition and apply some kind of formula to it to mimic the pixel distortion roduced by the volume effect.

Anyone skilled in math knows how to apply the LensEffect to a screen mouse coordinate?

2. ### pablobandinopla

Joined:
Jul 2, 2021
Posts:
97
According to chatGTP something like this could be the answer... i haven't tested this since i should have to create a custon lens distortion effect to expose th K123 coeficients...

Code (CSharp):
1. using UnityEngine;
2.
3. public class LensDistortionRayCasting : MonoBehaviour
4. {
5.     public Camera mainCamera;
6.     public float k1;
7.     public float k2;
8.     public float k3;
9.
10.     void Update()
11.     {
12.         // Get mouse position in screen coordinates
13.         Vector3 mousePosition = Input.mousePosition;
14.
15.         // Convert to normalized device coordinates (NDC)
16.         Vector2 ndc = new Vector2(mousePosition.x / Screen.width * 2f - 1f, mousePosition.y / Screen.height * 2f - 1f);
17.
18.         // Apply lens distortion effect
19.         Vector2 distortedNDC = ApplyLensDistortion(ndc, k1, k2, k3);
20.
21.         // Convert back to screen coordinates
22.         Vector3 distortedScreenPosition = new Vector3((distortedNDC.x + 1f) * 0.5f * Screen.width, (distortedNDC.y + 1f) * 0.5f * Screen.height, mousePosition.z);
23.
24.         // Cast ray from the post-distorted screen position
25.         Ray ray = mainCamera.ScreenPointToRay(distortedScreenPosition);
26.
27.         // Perform raycast operations as needed
28.         // ...
29.     }
30.
31.     Vector2 ApplyLensDistortion(Vector2 ndc, float k1, float k2, float k3)
32.     {
33.         float r2 = ndc.x * ndc.x + ndc.y * ndc.y;
34.         float distortionFactor = 1.0f + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2;
35.         return ndc * distortionFactor;
36.     }
37. }
38.

3. ### pablobandinopla

Joined:
Jul 2, 2021
Posts:
97
is this true? apparently there's no easy way to invert the distorion effect. ChatGPT:

To invert this distortion, you would need to find a set of equations that, given a distorted point, can solve for the undistorted point. Unfortunately, due to the complexity of the distortion equation involving higher-order terms, there's no simple closed-form solution to invert it directly.

Lens distortion is commonly corrected using iterative methods or optimization algorithms to find the undistorted point that would have caused the distorted point to appear where it is. Some popular algorithms for lens distortion correction include Newton-Raphson, Levenberg-Marquardt, or other non-linear optimization techniques. These methods typically involve iteratively refining the solution until the undistorted point is found.

4. ### pablobandinopla

Joined:
Jul 2, 2021
Posts:
97
i can't believe there's no way to do a simple raycast from a distorted screen.

If you use a fullscreen shader to create for example a fisheye effect, you lose the posibility to use screen raycasts to interact with the scene. because the raycasts doesn't follow the distortion and will point to the scene in the direction as if the distortion was not there...