Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by anaswattar · Feb 26, 2019 at 07:07 PM · raycastingimage effectsmatrixdistortion

Raycasting with Lense Distortion

I'm having an issue with raycasting while using Unity's Lens Distortion image effect.

Raycasts lose accuracy because they use the camera's projection matrix without accounting for the distortion of the image effect. I tried to find the matrix or algorithm used for the distortion but I haven't found anything.

Does any know what algorithm is used and how to modify the raycasting logic to account for the distortion?

Documentation about the effect is here: https://docs.unity3d.com/Packages/com.unity.postprocessing@2.0/api/UnityEngine.Rendering.PostProcessing.LensDistortion.html

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by adriafp · Apr 29, 2020 at 11:17 AM

Hello,

I'm facing the same problem.

I have 2 questions:

  1. Is settings a LensDistortion? And how it work? [SerializeField] private LensDistortion settings;

  2. What is the variable half?

Thanks in advance,

Cheers.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image anaswattar · Apr 29, 2020 at 10:43 PM 0
Share

oh sorry my bad. It's new Vector2(.5f, .5f) and yes, the variable settings is of type LensDistortion

avatar image horatiu665 · Jul 17, 2021 at 12:22 PM 0
Share

You can use this to get LensDistortion object from a PostProcessVolume reference:

 public PostProcessVolume postProcessVolumeForRaycast;
 public LensDistortion lensDistortionSettings => postProcessVolumeForRaycast.sharedProfile.GetSetting<LensDistortion>();

avatar image
0

Answer by anaswattar · Feb 28, 2019 at 12:34 AM

Ok after some research I was able to solve my problem.

The source of the lens distortion shader is here

https://github.com/Unity-Technologies/PostProcessing/blob/v2/PostProcessing/Shaders/Builtins/Distortion.hlsl

and its C# instructions are here

https://github.com/Unity-Technologies/PostProcessing/blob/v2/PostProcessing/Runtime/Effects/LensDistortion.cs

I ended up translating the shader code to C# so I could perform the same distortions on my mouse position. Here is my code:

 public Ray RaycastWithDistortion(Vector2 screenPosition)
 {
     if (settings.active)
     {
         return cam.ViewportPointToRay(DistortAndNormalizeScreenPosition(screenPosition));
     }
     return cam.ScreenPointToRay(screenPosition);
 }

Vector2 half = new Vector2(.5f, .5f);

 public Vector2 DistortAndNormalizeScreenPosition(Vector2 screenPosition)
 {
     return DistortUV(cam.ScreenToViewportPoint(screenPosition));
 }

 Vector2 DistortUV(Vector2 uv)
 {
     float amount = 1.6f * Mathf.Max(Mathf.Abs(settings.intensity.value), 1f);
     float theta = Mathf.Deg2Rad * Mathf.Min(160f, amount);
     float sigma = 2f * Mathf.Tan(theta * 0.5f);
     Vector4 distortionAmount = new Vector4(settings.intensity.value >= 0f ? theta : 1f / theta, sigma, 1f / settings.scale.value, settings.intensity.value);

     uv = ((uv - half) * distortionAmount.z) + half;

     Vector2 distortionCentre = new Vector2(settings.centerX.value, settings.centerY.value);
     Vector2 distortionScale = new Vector2(Mathf.Max(settings.intensityX.value, 1e-4f), Mathf.Max(settings.intensityY.value, 1e-4f));

     Vector2 ruv = distortionScale * (uv - half - distortionCentre);

     float ru = ruv.magnitude;

     if (distortionAmount.w > 0)
     {
         ru = Mathf.Tan(ru * distortionAmount.x) / (ru * distortionAmount.y);
     }
     else
     {
         ru = distortionAmount.x * Mathf.Atan(ru * distortionAmount.y) / ru;
     }
     uv = uv + (ruv * (ru - 1f));
     return uv;
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image horatiu665 · Jul 17, 2021 at 12:21 PM 0
Share

There may be an error here. After it didn't work for me initially (it was doing a distortion, but it was not the same as on the LensDistortion), I looked at the source code and in your interpreted version at line 16 there is distortionScale which uses x and y rather than z and w. Basically I think maybe distortionCenter and distortionScale are flipped.

I rewrote using the links you provided and then it seemed to be fixed (but please read on...).

I discovered another error from my part though, where in the Post-process Volume component, some of the options (namely CenterX and CenterY) were turned off, so they were rendered as zeros, but they had non-zero values, which meant this script used those values. Same for X and Y multiplier, in my case Y was deactivated, which means it was using the value from X (1 in my case). When setting the Y value explicitly to 1 and turning it on, your code kicked in and it was the same as the rendered version.

So basically for anyone else reading, make sure you set all the values explicitly in your post process component, else this uses the disabled values, not the default.

avatar image
0

Answer by kkiniaes · May 11 at 03:23 AM

The answer by @anaswattar got me close to what I needed, but I did some more digging and found that the formula is changed a little between PostProcessing V2 and the version I was using (Universal Render Pipeline 12.1.6)

The location of the code changed too:

  • The C# code can be found at com.unity.render-pipelines.universal@12.1.6\Runtime\Passes\PostProcessPass.cs

  • The shader code can be found at com.unity.render-pipelines.universal@12.1.6\Shaders\PostProcessing\UberPost.shader

I also converted the code a little differently than the other answer:

     float intensity = 0.5f, scale = 1f;
     Vector2 lensCenter = Vector2.one * 0.5f;
     Vector2 lensXYMult = Vector2.one;
     Vector2 half = Vector2.one * 0.5f;

     float amount = 1.6f * Mathf.Max(Mathf.Abs(intensity * 100f), 1f);
     float theta = Mathf.Deg2Rad * Mathf.Min(160f, amount);
     float sigma = 2f * Mathf.Tan(theta * 0.5f);
     Vector2 center = lensCenter * 2f - Vector2.one;
     Vector4 p1 = new Vector4(
         center.x,
         center.y,
         Mathf.Max(lensXYMult.x, 1e-4f),
         Mathf.Max(lensXYMult.y, 1e-4f)
     );
     Vector4 p2 = new Vector4(
         intensity >= 0f ? theta : 1f / theta,
         sigma,
         1f / scale,
         intensity * 100f
     );

     Vector2 uv = (_uv - half) * p2.z + half;
     Vector2 distAxis = new Vector2(p1.z, p1.w);
     Vector2 distCenter = new Vector2(p1.x, p1.y);
     Vector2 ruv = distAxis * (uv - half - distCenter);
     float ru = ruv.magnitude;

     if (p2.w > 0.0)
     {
         float wu = ru * p2.x;
         ru = Mathf.Tan(wu) * (1f/(ru * p2.y));
         uv = uv + ruv * (ru - 1f);
     }
     else
     {
         ru = (1f/ru) * p2.x * Mathf.Atan(ru * p2.y);
         uv = uv + ruv * (ru - 1f);
     }
     
     return uv;

Ultimately this helped me do the kind of raycasting I needed to do. In my case I don't need to worry about the distortion changing, so you could hook up those variables to read information from the post process settings. Hope that my digging saves someone else some time.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

174 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Distortion Shader for a Black Hole 0 Answers

Can i use raycast for something like a keypad? 2 Answers

Raycast not working (NO ERRORS!) 1 Answer

How to make a dynamic wall generation 0 Answers

Quaternion from transition matrix 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges