Search Unity

Low quality on Sprite and Line Renderer - not sharp enough [SOLVED]

Discussion in 'General Graphics' started by Ennaxor, May 28, 2018.

  1. Ennaxor

    Ennaxor

    Joined:
    Sep 2, 2013
    Posts:
    5
    Hi there! Looking for advices and help here:

    I put you in context:
    I'm developing a 2D game and I'm at the point of trying to show a simple "drop" animation, using a sprite of a circle made in Photoshop. I simply scale the sprite, here the example:
    https://gyazo.com/1b55f9f4737ee20a457e0b215e1dc5ee

    If you can notice it, you will see that when it's at its smallest size (scale 1, 1, 1), it isn't sharp enough and the quality is really poor. The used sprite is a 1048x1048 PNG, so it's quite big. I've tried changing everything on the imported settings:

    Changing the wrap mode, the filter mode to Point or Bilinear, etc, doesn't give any results at all. The animation is a simple scaling from 1 to 50 with a constant radius of 50. The bigger the scale, the better quality the sprite seems to have. If I use a sprite with a thicker arc, I get a smoother result, but it's not what I'm looking for. Of course, in my Project Settings I have anti-aliasing activated.

    Sooo, in order to fix this sharpness problem, I tried drawing the circle using Line Renderer. This is the result:


    And this is my script:

    Code (CSharp):
    1.  public override void UpdateShape(Vector2 newVertex) {
    2.             if (_vertices.Count < 2) {
    3.                 return;
    4.             }
    5.    
    6.             _vertices[_vertices.Count - 1] = newVertex;
    7.             transform.position = _vertices[0];
    8.    
    9.             var v0Relative = Vector2.zero;
    10.             var v1Relative = _vertices[1] - _vertices[0];
    11.             _meshFilter.mesh = CircleMesh(v0Relative, v1Relative, FillColor);
    12.    
    13.             _circleCollider2D.radius = Vector2.Distance(_vertices[0], _vertices[1]);
    14.    
    15.             _lineRenderer.positionCount = _meshFilter.mesh.vertices.Length;
    16.             _lineRenderer.SetPositions(_meshFilter.mesh.vertices);
    17.         }
    18.        
    19.         private static Mesh CircleMesh(Vector2 v0, Vector2 v1, Color fillColor) {
    20.             var radius = Vector2.Distance(v0, v1);
    21.             const float segmentOffset = 40f;
    22.             const float segmentMultiplier = 5f;
    23.             var numSegments = (int) (radius * segmentMultiplier + segmentOffset);
    24.    
    25.             var circleVertices = Enumerable.Range(0, numSegments)
    26.                 .Select(i => {
    27.                     var theta = 2 * Mathf.PI * i / numSegments;
    28.                     return new Vector2(Mathf.Cos(theta), Mathf.Sin(theta)) * radius;
    29.                 })
    30.                 .ToArray();
    31.    
    32.             var triangles = new Triangulator(circleVertices).Triangulate();
    33.             var colors = Enumerable.Repeat(fillColor, circleVertices.Length).ToArray();
    34.    
    35.             var mesh = new Mesh {
    36.                 name = "Circle",
    37.                 vertices = circleVertices.ToVector3(),
    38.                 triangles = triangles,
    39.                 colors = colors
    40.             };
    41.    
    42.             mesh.RecalculateNormals();
    43.             mesh.RecalculateBounds();
    44.             mesh.RecalculateTangents();
    45.    
    46.             return mesh;
    47.         }
    As you can see, I still get 0 sharpness on my drawn circles using Line Renderer! Got to mention that I have tried modifiying the number of capVertices and cornerVertices, but still no results. Maybe there are special shaders to resolve this problem? I have no idea.

    I'm open to any solutions and happy to hear about your advices! Thanks a lot in advance :D
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Enable mipmaps to start with.

    The ultimate way in my opinion is to actually draw a circle in the shader and use screen space derivatives to do antialiasing. That does require shader model 3 support. (And some shader programming knowledge.)

    The other way would be to use a signed distance field. You might be able to use TextMeshPro for that, because it also uses signed distance fields.
     
    theANMATOR2b likes this.
  3. Ennaxor

    Ennaxor

    Joined:
    Sep 2, 2013
    Posts:
    5
    Ohhh, thanks so much jvo3dc!

    Just by enabling mipmaps worked, ah... Why didn't I try it? I just really thought it wouldn't work for this case scenario.
    I also followed this post someone linked me:
    https://www.reddit.com/r/Unity2D/comments/6fs8pn/why_are_my_sprites_pixelated_in_unity_although/ and did this:
    "Pixel perfect orthographic camera size: (Vert Resolution/Pixels per Unit) 0.5. For example: given a sprite imported with 64 Pixels per Unit, and a 1280x720 game resolution the camera size should be (720/64) 0.5 = 5.625"

    Thanks a lot! I hope this post will help someone at some point :)

     
    theANMATOR2b likes this.