How to make plane look curved?

Hi! could anyone help me how to make plane and farther object look curved, just like Subway Surfers Video Gameplay


more ▼

asked Jul 23, 2012 at 08:42 AM

star3vil gravatar image

58 8 11 17

(comments are locked)
10|3000 characters needed characters left

5 answers: sort voted first

Unfortunately it's not possible to do this just with a projection matrix since it only can do linear projection. What you want requires z². It is possible to do this with a custom shader, but your geometry need to have "enough" vertices along the "bend". See this example in Minecraft. I think you can't do the bending in the fragment shader since it requires you to offset the geometry depending on the distance to the camera. AFAIK this can only be done in the vertex shader.

I'm far from being a shader expert, so it take a while until it worked (i hate syntax errors and totally useless errors :D). I've written a very simple shader that can bend the objects that are drawn with it. However it has one downside: Every object needs a custom shader or it won't fit together with the other things.

This example scene has 3 objects in a row (two planes and one cube). The camera is sliding linearly on the z-axis over the objects. The first plane has my curved shader, the second plane has a normal diffuse shader and the cube also has my curved shader.


I've packed the sample together in a package.

Here's the important part of the vertex shader:

 v2f vert (appdata_base v)
     v2f o;
     // The vertex position in view-space (camera space)
     float4 vPos = mul (UNITY_MATRIX_MV, v.vertex);
     // Get distance from camera and scale it down with the global _Dist parameter
     float zOff = vPos.z/_Dist;
     // Add the offset with a quadratic curve to the vertex position
     vPos += _QOffset*zOff*zOff;
     o.pos = mul (UNITY_MATRIX_P, vPos);
     o.uv = v.texcoord;
     return o;

_Dist wouldn't be necessary. It just scales the whole vector, but it helps to find nice values ;)

As you can see the first plane bends quite nicely because the default Unity plane consists of 10x10 quads, so there are many vertices along the bending edge.

The cube doesn't have subdivs. The vertices bend correctly, but the edges will stay linear.

The second plane keep the original position since it doesn't have a bending shader.

Keep in mind that the actual objects will be on a straight line. This is very useful for physics and collisions. Only the view is bent.
Note that the visibillity check that is performed by Unity does not take the bending into account. So an object could be bend outside of the viewport, but it is still rendered because the actual position is still in view. Also the other way round. If an object would be bend into the viewport, but the actual object is outside of the viewing frustum, the object will not be drawn at all.

more ▼

answered Jul 23, 2012 at 11:23 AM

Bunny83 gravatar image

85.9k 31 169 438

great work, Many Many Thanks! Now I'm going to make a 'runner' game just to try this out =]

Was curious anyway after seeing stuff like this : http://www.youtube.com/watch?v=JpksyojwqzE

Jul 23, 2012 at 03:17 PM alucardj

thank a lot Bunny :D

Jul 24, 2012 at 12:57 AM star3vil

Hi Bunny! a bit more problem is come out. when i changed shader to Custom/Curved, why the function " Renderer.material.SetTextureOffset("_MainTex", Vector2(offset,0)); " not working? Please help :(

Jul 24, 2012 at 07:00 AM star3vil

ok! Thanks again!

Jul 24, 2012 at 10:30 AM star3vil

I am exploring this shader and quite impressed, Bunny83. Thanks! If doing similar to Subway Surfers, we would apply this shader for the train track. How should we do for objects along the track, say the train?

Jan 25, 2013 at 10:05 AM t.a.
(comments are locked)
10|3000 characters needed characters left

Hey ! I've made shader that gives complete subway surfers look. Try to fiddle with the vertices in view matrix. (i.e their z axis). I made through vertex and fragment shaders. Message again if you get stuck anywhere

more ▼

answered Mar 06 at 08:08 AM

Pranav Paharia gravatar image

Pranav Paharia

impressive !

Mar 06 at 08:22 AM Fattie
(comments are locked)
10|3000 characters needed characters left


I try to connect this shader property with the default shader Mobile/Particles/Additive. But i can't get the exact solution.

Please help me

more ▼

answered Mar 06 at 07:42 AM

sruthidivakar gravatar image

16 3 3 7

(comments are locked)
10|3000 characters needed characters left

here i put the shader,

Shader "Custom/Curved" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _QOffset ("Offset", Vector) = (0,0,0,0) _Brightness ("Brightness", Float) = 0.0 _Dist ("Distance", Float) = 100.0 }

 SubShader {
     Tags { "Queue" = "Transparent"}
         Blend SrcAlpha OneMinusSrcAlpha 
         #pragma vertex vert
         #pragma fragment frag
         #include "UnityCG.cginc"

         sampler2D _MainTex;
         float4 _QOffset;
         float _Dist;
         float _Brightness;
         struct v2f {
             float4 pos : SV_POSITION;
             float4 uv : TEXCOORD0;
             float3 viewDir : TEXCOORD1;
             fixed4 color : COLOR;

         v2f vert (appdata_full v)
            v2f o;
            float4 vPos = mul (UNITY_MATRIX_MV, v.vertex);
            float zOff = vPos.z/_Dist;
            vPos += _QOffset*zOff*zOff;
            o.pos = mul (UNITY_MATRIX_P, vPos);
            o.uv = v.texcoord;
            return o;
         half4 frag (v2f i) : COLOR0
               half4 col = tex2D(_MainTex, i.uv.xy);
               col *= UNITY_LIGHTMODEL_AMBIENT*_Brightness;
             return col;
 FallBack "Diffuse"


more ▼

answered Jun 18 at 03:38 PM

richyz gravatar image


(comments are locked)
10|3000 characters needed characters left

Have a look at the Curved World - Screen Space Curvature Shader.


alt text

alt text

more ▼

answered Dec 11 at 05:14 PM

Arkhivrag gravatar image

16 18 16 18

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

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

By Email:

Once you sign in you will be able to subscribe for any updates here



Answers and Comments



asked: Jul 23, 2012 at 08:42 AM

Seen: 16393 times

Last Updated: Dec 11 at 05:14 PM