Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
avatar image
0
Question by MatrixTai · Jun 20, 2017 at 08:14 AM · camerashaderresolutionpost-process-effectdistortion

Camera Distortion effect needed improve (SOLVED)

I write my own camera distortion effect like following:

             sampler2D _MainTex, _DistortionMap;
 
             struct VertexData {
                 float4 vertex : POSITION;
                 float2 uv : TEXCOORD0;
             };
 
             struct Interpolators {
                 float4 pos : SV_POSITION;
                 float2 uv : TEXCOORD0;
             };
 
             Interpolators VertexProgram (VertexData v) {
                 Interpolators i;
                 i.pos = UnityObjectToClipPos(v.vertex);
                 i.uv = v.uv;
                 return i;
             }
 
             float4 FragmentProgram (Interpolators i) : SV_Target {
                 float2 distort = tex2D(_DistortionMap, i.uv).rg;
                 distort = distort * 2 - 1;
                 i.uv += distort;
                 float3 sourceColor = tex2D(_MainTex, i.uv).rgb;
                 return float4(sourceColor, 1);
             }
 
             ENDCG


While this is attached to the camera by

     void OnRenderImage(RenderTexture src, RenderTexture dest)
     {
         Graphics.Blit(src, dest, material);
     }

As you can notice I use a texture map which contain the red and green channel to change the x,y position. The map I used is this, which will squeeze everything a little bit to the middle. alt text

However, the result comes out to be

alt text

It looks like the image is distorted slice by slice but not pixel by pixel, how to improve it? Thank you.

distortion-error.png (378.4 kB)
distort2.png (63.8 kB)
Comment
Add comment · Show 8
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 AtGfx · Jun 20, 2017 at 08:54 AM 0
Share

Hi !

I think that there is a problem with your distortion and you do not make what you think.

In your FragmentProgram the value of distort lies in the range [-1,1] (because it comes from distort = distort ([0,1]) * 2 - 1 then you make i.uv += distort so i.uv lies in range [-1, 2] wich is not acceptable for a uv texture that should be in the range [0,1]. You can try to rerange it such that your uv fit in a correct space (if I'm correct, add 1 to your uv then divide by 3).

According to your map, your mistake can lead to sample the texture over the range [0,1] and as your map is kind of smooth, it can explain why you see some stripes on your image.

Hope it helps ;)

avatar image MatrixTai AtGfx · Jun 20, 2017 at 09:27 AM 0
Share

I don't think that's the correct way. I try to add a line i.uv = saturate(i.uv); But nothing's change. As I know TEXCOORD will be automatically saturated now, so probably not the right way. Thx for ur help.

avatar image AtGfx MatrixTai · Jun 20, 2017 at 10:16 AM 0
Share

Take care that saturate is only a clamp so it's indeed the same if you put it. What is exactly the effect/distortion you want to get ? And can you give the full shader (I can try to play with it, maybe I will get something ^^) ?

Show more comments
avatar image MatrixTai AtGfx · Jun 21, 2017 at 05:07 AM 0
Share

@AtGfx Just simply assign a material using Custom/DistortionEffect. Dun assign any _$$anonymous$$ainTex, it will simply grab from the camera, just change the Distortion map. And then recall this material in the camera attached with "DistortionEffect.cs". If you prefer to use the shader directly, simply write few lines of code to generate a material using that shader in the "DistortionEffect.cs".

avatar image AtGfx MatrixTai · Jun 21, 2017 at 03:01 PM 0
Share

I tried to put something in evidence but I cannot understand what happend exactly (I got the same results as you...).

$$anonymous$$aybe there are problem with the sampling because your texture is 512x512 and your res is 16:9 (I suppose), or there can be problem with the generation of the texture, etc.

Another possibility would be to calculate the distortion with some function and you apply it directly to your i.uv. If it works, it means that your texture is actually the problem.

I tried with a very simple texture which translate u and v to 0.1 and everything goes well. Troubles come when I try to put a linear gradient in the texture with Photoshop (this is why I think that the texture is the problem).

avatar image MatrixTai AtGfx · Jun 21, 2017 at 04:52 PM 0
Share

Yes, I agree, I think the problem comes from when we sampling the image captured by camera with texture, the image is not sampled pixel by pixel but slice by slice for better performance. Therefore, position translation is O$$anonymous$$, but re-scaling fails.

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Eno-Khaon · Jun 20, 2017 at 08:06 PM

The problem may actually be simpler than it seems.

After taking a quick look at it, your distortion texture appears to be TOO BIG!

What you're looking for is interpolation between pixels to smooth out the effect across the screen. However, with a 512x512 texture, most adjacent pixels are the same color. As an example, say you have a simple, 4 pixel, black-white-white-black texture:

b-w-w-b (Note: Image is intentionally oversized for illustrative purposes)

When the pixels are interpolated and viewed up close, the texture would look something like this:

still b-w-w-b Note that the two inside white pixels result in a large, white field which doesn't blend with the neighboring black pixels. That's because they're not supposed to blend with anything but their immediate neighbors.

This is the problem you're experiencing with your distortion texture. Most pixels are actually the same color as their neighbors, so blending them results in no change of color.

So, there are two main ways you can look at solving this:

1) Change your distortion texture to be no more than 256 pixels wide (and/or tall), using a different value for every pixel to allow interpolation at any point. For reference, a 2x2 texture could functionally provide a linear curve across the entire screen, by letting the texture rendering (linearly) interpolate all the way from one extreme to the other

2) Programmatically distort the screen instead, based on the uv coordinates of the base render. This cuts out the potential to distort the image in specific, directed ways, but will allow you to create single-purpose variations with (near-) infinite precision.

Regardless of which you choose, you may also want to add a scale to your shader, to increase or decrease the level of distortion.

 Properties
 {
     // ...
     _ScaleOffset("Scale and Offset", Vector) = (0.25, 0, 0, 0) // scaleX, scaleY, offsetX, offsetY
 }
 
 float4 _ScaleOffset;
 // ...
 
 float4 FragmentProgram (Interpolators i) : SV_Target
 {
     // ...
     // Texture-based example
     float2 distort = tex2D(_DistortionMap, i.uv).rg;
     distort = distort * 2 - 1;
     distort = distort * _ScaleOffset.xy + _ScaleOffset.zw;
     // ...
 }

Edit: Added note about a 2x2 texture's potential use


colorsblended.png (2.6 kB)
colorsunblended.png (380 B)
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 MatrixTai · Jun 21, 2017 at 04:55 AM 0
Share

@$$anonymous$$o-$$anonymous$$haon I tried to use a 128x128 or 256x256 texture, the results are the same. And then I add the code you written, yes, the result is better when the scaleoffset becomes close to zero, but it just return to the origin. The problem of slice by slice gradient is still here. Thx a lot.

avatar image Eno-Khaon MatrixTai · Jun 21, 2017 at 06:29 PM 0
Share

Ah, right. I knew I was forgetting something...

The other 90% of the problem is DXT texture compression on your distortion map.

Get rid of that and the 4x4 texture blocks will be gone. Despite how the compression is supposed to work functionally (take two color extremes and blend between them... should work perfectly well with a fixed gradient), it rarely succeeds at it.

avatar image
0

Answer by MatrixTai · Jun 22, 2017 at 05:59 AM

Oh, I get it. This is indeed not a big problem.... I change the texture to this, then everything correct. My original one is mistakenly transferring both x-axis and y-axis. alt text it is just the error of texture. Sorry for bothering you guys time. @Eno-Khano and @AtGfx


distort3.png (78.8 kB)
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 AtGfx · Jun 22, 2017 at 07:07 AM 0
Share

No problem ;)

If it works you can try to set a green linear gradient from top to bottom (or set a different texture for x distortion and y distortion). Normally you should be able to distort your output in both directions !

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

125 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

Related Questions

Rendering different shader when camera get near object 1 Answer

2D and distortion shader 1 Answer

Camera horizontal distortion? 1 Answer

Vertex based screen deformation fx 0 Answers

Post Effect to certain objects? 1 Answer


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