title: Space curvature bending in Unity3D as Post Effect/Image Effect
body: <p>I'm trying to archieve a chilindrical effect like this on Unity3D:</p>
  <p><a href="https://i.stack.imgur.com/TiJ3z.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TiJ3z.png" alt="enter image description here" /></a></p>
  <p>But every solution is using material based shader, sadly I must have a Post Process effect or an Image Effect, for these reasons:</p>
  <ul>
  <li>One map out of 30 needs to use this effect and there are many materials that are shared between them...</li>
  <li>Every solution is vertex based. I've done some experiments but I have models with different polygon count, this means that the effect would create visual artifacts (but this can by fixed by editing the 3d models eventually).</li>
  <li>I'm at an advanced stage of development.</li>
  </ul>
  <p>Do you think it's possible to create a simple effect (even a fake one) that moves the pixels downwards/upwards based on the distance to the camera? (I assume I need to use the depth map)</p>
  <p>I've tried very hard but I had no success, the effect doesn't do anything or just won't compile :(</p>
  <p>This is the best I could come up with, the grayscale in the frag method is only to check if the shader is working, but once I define the Vert function the grayscale disappears and the shader does nothing.</p>
  <pre><code>Shader &quot;Hidden/Custom/WorldCurvature&quot;
  {
  HLSLINCLUDE
  
      #include &quot;Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl&quot;
  
      TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
      float _Bend;
      
      struct Attributes
      {
          float4 vertex : POSITION;
          float2 texcoord : TEXCOORD0;
      };
      
      struct Varyings
      {
          float4 vertex : SV_POSITION;
          float2 texcoord : TEXCOORD0;
      };
  
      float4 Frag(Varyings i) : SV_Target
      {
          float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
          float luminance = dot(color.rgb, float3(0.2126729, 0.7151522, 0.0721750));
          color.rgb = lerp(color.rgb, luminance.xxx, _Bend.xxx);
          return color;
      }  
      
      Varyings Vert(Attributes v)
      {
          Varyings o;
          float4 vv = mul(unity_ObjectToWorld, v.vertex );
          vv.xyz -= _WorldSpaceCameraPos.xyz;
          vv = float4( 0.0f, (vv.x * vv.x) * - _Bend, 0.0f, 0.0f );
          v.vertex += mul(unity_WorldToCamera, vv);
          o.vertex = mul(unity_WorldToCamera, vv);
          o.texcoord = v.texcoord;
          return o;
      }
  
  ENDHLSL
  
  SubShader
  {
      Cull Off ZWrite Off ZTest Always
  
      Pass
      {
          HLSLPROGRAM
  
              #pragma vertex Vert
              #pragma fragment Frag
  
          ENDHLSL
      }
  }
  }
  </code></pre>
  <p>I've done another experiment but I think it would only work in a 2D environment, here the image stops once I activate the image effect:</p>
  <pre><code>Shader &quot;Hidden/Custom/CylinderImageEffect&quot; {
   Properties {
       _MainTex (&quot;Texture&quot;, 2D) = &quot;white&quot; {}
   }
  
   SubShader {
       Cull Off ZWrite Off ZTest Always
  
       Pass {
           CGPROGRAM
           #pragma vertex vert
           #pragma fragment frag
  
           #include &quot;UnityCG.cginc&quot;
  
           struct v2f {
               float4 vertex : SV_POSITION;
               float2 uv : TEXCOORD0;
           };
  
          v2f vert( appdata_img v ) 
          {
              v2f o;
              o.vertex = UnityObjectToClipPos(v.vertex);
              o.uv = v.texcoord.xy;
              return o;
          } 
  
           sampler2D _MainTex;
  
           fixed4 frag (v2f i) : SV_Target {
               i.uv.x = 1 - acos(i.uv.x * 2 - 1) / 3.14159265;
               return tex2D(_MainTex, i.uv);
           }
           ENDCG
       }
   }
   }
  </code></pre>