Search Unity

Vertex shader curve

Discussion in 'Shaders' started by slole, Jun 30, 2017.

  1. slole

    slole

    Joined:
    Dec 23, 2016
    Posts:
    4
    I have created a simple sprite shader that tekes the sprites vertices and displaces them based on the world position on the x axis. However that gives me a rather linear result: the sides of the sprite are still straight. However I would like to bend the sprite in a way that bends the sides in a curve. How would I go about doing that? Can I just increase the number of the vertices on the sprite renderer and apply the same shader so that I get a more curved result? Or should I just move the warping mechanism to the fragment shader?

    the shader:
    Code (CSharp):
    1. v2f vert(appdata_t IN)
    2.             {
    3.                 v2f OUT;
    4.                 UNITY_SETUP_INSTANCE_ID(IN);
    5.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
    6.                 float3 worldPos = mul(unity_ObjectToWorld, IN.vertex).xyz;
    7.                 OUT.vertex = UnityObjectToClipPos(IN.vertex + (IN.vertex * (sin(abs(worldPos.x / 2)) * 2 - 1) * 0.4f * (1 / (pow(worldPos.x, 2) + 1))) + float4((cos(abs(worldPos.x) / 2) * 3 + 1) * 0.4f * worldPos.x * (1 / (pow(worldPos.x, 2) + 1)), 0, 0, 0));
    8.                 OUT.texcoord = IN.texcoord;
    9.                 OUT.color = IN.color * _Color;
    10.                 #ifdef PIXELSNAP_ON
    11.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    12.                 #endif
    13.  
    14.                 return OUT;
    15.             }
     
  2. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    A picture to illustrate the problem?
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Your basic sprite is just a quad with four vertices, so yes you'll just get straight edges trying to wiggle it.

    You can do the wiggle in the pixel shader, but Unity's sprite packing is fairly tight so you can only wiggle but about 2 texels before you'll start seeing the next sprite in the atlas, if you're using a sprite atlas.

    You can use a custom sprite mesh with a higher poly count, or a tesselation shader. I would suggest just using a custom mesh as tesselation is limited to DX11 or equivalent level OpenGL.
    https://docs.unity3d.com/ScriptReference/Sprite.OverrideGeometry.html
    https://docs.unity3d.com/Manual/SL-SurfaceShaderTessellation.html

    You'll have to make the custom meshes in editor via script. If you search the forums you should find posts on how to actually use OverrideGeometry.
     
  4. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    fwiw, you can set your sprites to full rect instead of tight in the import settings which will make your quad the size you sliced it in the sprite editor, not the cropped size Unity normally gives you. If you can live with the overdraw this is a way to get more texel space to do pixel shader stuff.