Search Unity

Unity Vector Graphics Preview Package

Discussion in '2D Experimental Preview' started by rustum, May 4, 2018.

  1. rejemy

    rejemy

    Joined:
    Nov 1, 2013
    Posts:
    5
    First off, thanks so much to mcoted3d for being so patient and helpful in this forum, and I'm really happy that it's possible to import SVGs into Unity now. And I apologize, I'm sure this question has been asked, but I can't find it with search.

    For my weird use case I want to render SVGs with a MeshRenderer and custom shader, so I want to access the actual mesh the SVGImporter generates, and the sprite doesn't help because it doesn't give access to the vertex colors. Is there a way to hook in during asset import to get the generated mesh object? I suppose I can read the SVG asset text myself and do my own tessellation, but then I'm processing each asset twice, and it would be nice to have the exact same mesh used to make the sprite so they look the same. The project will eventually have thousands of small SVGs and it would be nice to keep asset processing times down.

    Thanks so much!
     
    Last edited: Sep 14, 2019
  2. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    There's a way to get the sprite's vertex color using this well hidden extension:
    https://docs.unity3d.com/ScriptReference/Experimental.U2D.SpriteDataAccessExtensions.html

    Then you can simply do this:
    Code (CSharp):
    1. sprite.GetVertexAttribute<Color32>(VertexAttribute.Color)
    It's still a bit sad that you'll have to generate this useless intermediate sprite before converting to a mesh, but it's not too bad if done at import time. Otherwise, importing directly into a mesh is on our internal roadmap.

    Hope this helps!
     
  3. rejemy

    rejemy

    Joined:
    Nov 1, 2013
    Posts:
    5
    Perfect, thanks!
     
  4. sirian_ye

    sirian_ye

    Joined:
    Sep 4, 2019
    Posts:
    4
    Hi guys

    Is it possible to make the vector graphics selectable? I understand there is no interactive function yet, but is there any work around ways to do it?

    Also if my scene have multiple root, do I need to create multiple scenes?

    thank in advance for any reply!
     
  5. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    Not out-of-the-box, but we discussed a few alternatives here:
    https://forum.unity.com/threads/vector-graphics-preview-package.529845/page-15#post-4811951

    Not sure I understand this question. Are you talking about Unity scenes or the vector "Scene" class of the vector graphics package? If the latter, one reason to keep your vector scenes separate is to be able to tessellate them separately. Let me know if I misunderstood.
     
    sirian_ye likes this.
  6. sirian_ye

    sirian_ye

    Joined:
    Sep 4, 2019
    Posts:
    4
    Thanks very much for the great answer!

    Sorry for the ambiguous description. I mean the vector scene class. My data structure cannot put all the scenenode under one single root due to the current graph structure has multiple roots. It is a sankey diagram https://en.wikipedia.org/wiki/Sankey_diagram. So if I want to create such, do I need to create multiple scenes or I can fit them in one single scene in some way? I would prefer one single scene if it is possible.
     
  7. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    341
    @mcoted3d Thanks for adding the preserve aspect ratio feature. I had made my own SVGImage class to do the same thing. But it required a lot of duplicating code out of the SVG package to make it happen. Yuck. Now all clean again!

    So along the same lines... how about 9-slice support pretty please?
     
  8. Waterlane

    Waterlane

    Joined:
    Mar 13, 2015
    Posts:
    151
    'any idea when this will be out of 'preview'?
     
  9. sirian_ye

    sirian_ye

    Joined:
    Sep 4, 2019
    Posts:
    4
    Hi guys. me again. currently playing around the Vector graphics API. There is a problem that VectorUtils.GenerateAtlas always returns a null TextureAtlas.

    My code just simply makes some rectangles and convert them into meshes. Previous steps look ok for me. VectorUtils.Geometry got indices and vertices after tessellation. Then I cannot get textureAltas for uvs. I searched in the forum for similar cases, but didnt find anything. I might make some stupid mistakes...

    Thanks very much for any help!

    Code (CSharp):
    1.  
    2.         List<Shape> shapes = new List<Shape>();
    3.  
    4.         Shape rectangle = new Shape();
    5.         foreach(var nodeGroup in result)
    6.         {
    7.             for(int i =0; i < nodeGroup.Value.Count; i++)
    8.             {
    9.                 VectorUtils.MakeRectangleShape(rectangle, new Rect( nodeGroup.Value[i].X, nodeGroup.Value[i].Y, nodeGroup.Value[i].Width, nodeGroup.Value[i].Height));
    10.                 rectangle.Fill = new SolidFill() { Color = Color.blue };
    11.                 rectangle.PathProps = new PathProperties() {
    12.                     Stroke = new Stroke() { Color = Color.red }
    13.                 };
    14.  
    15.                 shapes.Add(rectangle);
    16.             }
    17.         }
    18.  
    19.         // only uses one rectangle for the testing purpose
    20.         Scene scene = new Scene() {
    21.             Root = new SceneNode() { Shapes = new List<Shape> {shapes[0]} }
    22.         };
    23.  
    24.         VectorUtils.TessellationOptions options = new VectorUtils.TessellationOptions()
    25.         {
    26.             StepDistance = 5.0f,
    27.             MaxCordDeviation = float.MaxValue,
    28.             MaxTanAngleDeviation = Mathf.PI / 2.0f,
    29.             SamplingStepSize = 1.0f
    30.         };
    31.  
    32.         List<VectorUtils.Geometry> geoms = VectorUtils.TessellateScene(scene, options);
    33.         // here altas is always a null object
    34.         VectorUtils.TextureAtlas altas = VectorUtils.GenerateAtlas(geoms, 128);
    35.         VectorUtils.FillUVs(geoms, altas);
     
    Last edited: Sep 23, 2019
  10. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    You can of course use a single scene. The SceneNode class has a list of children, so the way to do it would be to store all of your nodes under the
    scene.Root.Children
    list.
     
  11. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    We will have to re-evaluate how hard is this feature to implement. The last time we checked, it felt non-trivial given that the sprite geometry has to be recomputed whenever the sprite size changes. And the sprite system doesn't like it when its geometry gets changed outside of a runtime context. There may be recent improvements in the sprite system on that matter, so I'll have another fresh look.
     
  12. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    The texture atlas is only generated when needed to store textured fills and gradient fills. If your scene only uses solid fills and strokes, a texture atlas won't be generated (and you can skip the FillUVs() call altogether as well).
     
    sirian_ye likes this.
  13. sirian_ye

    sirian_ye

    Joined:
    Sep 4, 2019
    Posts:
    4
    I need the UV since I need to draw the shape mesh on GUI as populateMesh. So the problem is the fill if change the fill then it can generate atlas and UV? Got it, thanks very much!

    Besides of draw svg as tessellated mesh, is there any other way to draw vector image on GUI?
     
  14. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    You can have a look at the public FillUVs() method in the package. It basically set the UVs array on each Geometry item to the normalized [0,1] value of the vertex position into the bounding box. You can probably fill it yourself quite easily. Otherwise, using a simple gradient fill would work as well.

    For OnGUI() content, the easiest is to use GL calls: https://docs.unity3d.com/ScriptReference/GL.html

    If you want the SVG to fill the whole viewport, you can use the VectorUtils.RenderSprite() method which will generate the GL calls for you. This internally sets an orthographic projection, so this will fill the viewport. Otherwise, you'll have to use GL calls yourself.
     
  15. Raubi

    Raubi

    Joined:
    Apr 3, 2015
    Posts:
    8
    Hi,

    is there anything I can do regarding the "SpriteColor or SpriteFlip for renderers that are not sprite renderers. Values are undefined" error? I simply exported a SVG from Illustrator and get after importing into Unity the given error.

    Unity version: 2019.2.5f1
    Vector Package Version: 2.0.0-preview.5 (same error with preview.6)

    The Vector I tried to import is enclosed.

    Thanks!

    Edit: I have not used the SVG graphics somewhere yet. I simply imported it and the warning showed up.
     

    Attached Files:

  16. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    I didn't notice this issue. If you could file a bug report (Help > Report a Bug...), that would be helpful. There might be a project-specific setting that triggers this.
     
  17. Rosethornian

    Rosethornian

    Joined:
    Apr 26, 2018
    Posts:
    32
    @mcoted3d Vector graphics appear to be broken in both the current pre-release versions namely 2019.3.0b4 and 2020.1.0a3.

    Is this correct or is it just me?
     
  18. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    Not just you. I recently pushed 2.0.0-preview.6 to fix this, you should give it a try!

    EDIT: Note that because of a public API change that occurred in beta4, you'll have to use 2.0.0-preview.5 when using 2019.3 beta1 to beta3. For 2019.3 beta4 and onward, use 2.0.0-preview.6. I know this is confusing.
     
    Last edited: Sep 26, 2019
  19. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    341
    @mcoted3d Any word on the issue where UI in overlay mode won't anti-alias? Working around this leads to other issues that if antialiasing functioned we could just avoid.
     
  20. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    Given that the UI in overlay mode is drawn after the MSAA framebuffer is resolved, turning on MSAA antialiasing won't have any effect there. To solve this, we would need to provide another method to display antialiased primitives. We are looking at ways to render vector elements with antialiasing evaluated on the GPU. This would provide antialiasing even with MSAA turned off. However, this is a major change and will take some time.

    I'm not sure which workaround is causing issues in your situation. If that works for you, I think the simplest would be to use the "Camera Overlay" mode on your canvas. If the camera is MSAA-enabled, you should get good results.
     
  21. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    341
    It's one of those things where every work-around presents other obstacles. Overlay doesn't work due to the lack of antialiasing. So we use camera overly and render the UI to an offscreen texture, which we then post process (antialiasing, etc.) and then render as a normal UI image in a normal canvas. This works fine in the standard rendering pipeline... where we are prototyping.... but will not work in Universal or HDRP. The issue is you the render targets don't support Alpha there (and issue I've screamed myself horse about now).

    In fact, there is no way to use vector graphics in a UI in, say, HDRP that doesn't look bad (due to a lack of anti-aliasing). You can try to do it without rendering to a texture and then attempting to have antialiasing happen on the UI camera, but it can make a confusing mess of things as the framebuffer contains both the scene and the UI. Odd results in temporal AA, etc.

    Since the standard pipeline is deprecated, we have to move to HDRP (Universal is not feature complete enough for our needs).

    Still trying to find some simple way to do what should be simple: Make a game with a vector-based UI. You can do it, but doing it at anything resembling production polish. Worse, not sure if anyone is connecting the dots over there that these things.... each developed in isolation.... have to meld together as a cohesive solution.
     
    Korindian likes this.
  22. rejemy

    rejemy

    Joined:
    Nov 1, 2013
    Posts:
    5
    Re: Bug in SVG Polygons with rounded corners

    I'm seeing a possible bug in the SVG importer: Rounded corners seem to work fine in stroked paths and polylines, but NOT in polygons. Here's a simple example where the polyline and path both have rounded corners rendering correctly, and a polygon where they render as sharp corners instead.

    <?xml version="1.0" encoding="utf-8"?>
    <svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
    <polygon style="fill: rgb(216, 216, 216); stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 23px;" points="147.729 64.397 39.774 162.667 161.614 299.45 247.57 133.418"/>
    <polyline style="fill: rgb(216, 216, 216); stroke: rgb(0, 0, 0); stroke-width: 15px; stroke-linecap: round; stroke-linejoin: round;" points="359.815 235.512 272.293 333.42 362.825 375.612 421.214 291.739"/>
    <path d="M 381.923 42.504 C 356.526 50.376 330.444 56.307 305.733 66.121 C 303.767 66.902 307.892 69.811 309.381 71.313 C 313.334 75.302 316.838 80.232 321.972 82.509 C 347.985 94.047 375.013 103.194 401.949 112.372 C 413.579 116.335 425.876 118.085 437.557 121.892 C 439.753 122.608 445.279 124.724 443.254 125.835 C 394.11 152.806 340.56 171.68 292.941 201.259 C 281.149 208.584 276.356 223.524 268.063 234.656" style="stroke: rgb(0, 0, 0); fill: none; stroke-width: 12px; stroke-linecap: round; stroke-linejoin: round;"/>
    </svg>

    Should I submit through the Unity bug system, or is this forum the right place? Thanks!
     
  23. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    445
  24. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    Yes, please file a bug. This is the best way to make sure this will be tracked by our team! Thank you!
     
  25. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    First, thank you very much for the detailed explanation of your situation, it is very appreciated. We are aware of most of the problems you mentioned, and having real users sharing their real problems helps us prioritize these issues.

    We do most of our development on the standard render pipeline since most of our users are using it. We will include more HDRP/URP testing in the short term, so we will try to get back to you shortly with adequate workarounds.

    In the longer term, having antialiased SVG primitives without relying on hardware MSAA would be the most obvious solution. But, as mentioned earlier, this is more involved in the SVGImporter side of things.
     
  26. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    341
    I appreciate the acknowledgement of the issues. It's been tough for us as we're working on a pretty large-scale project (8 figure dev budget / 30+ team size) . With Unity being in this strange "in between" state right now, we're having a hard time making progress in a way that makes sense. We have to show progress to secure green-lights as we go, but ultimately are really banking on eventually being able to move to HDRP for competitive reasons. Right now we can't make it work at all, with SVG being the gating issue. The longer we are in standard pipeline space, the more worse this is going to be for us when we try to switch.

    As for this issue, shouldn't there be some simple way to get the order right on when the MSAA occurs? Or something?

    If you have to do it inside of SVG itself, then the only way I've seen it done in the past is with edges being rendered with this sorta shark-fin geomeotry that is always scaled to the pixel grid. This creates the antialiasing on vector geometry (scaleform did this) at the cost of a lot of gemoetry and geometry operations. Not ideal.
     
  27. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    Probably. I think HDRP is basically using a deferred pipeline, so MSAA doesn't really make sense in that context. We will have to dive deep into HRDP to see what works and what doesn't.

    SVG antialiasing is a hot topic in our team right now. Adding fins is one way to do it, but as you mentioned, it generates quite a bit of extra geometry. This is a big downside.

    We're also exploring variants of "distance to the curve" that are evaluated per-fragment on the GPU. A distance-field approach, if done right, would allow generating fewer triangles than a tessellated approach while achieving high-quality antialiasing. However, the challenge is to make it efficient on the GPU, as we would ideally want this to work on mobile as well.

    All approaches have pros and cons, and so far we haven't committed to a single solution. But we'll hopefully get there!
     
    Korindian likes this.
  28. rejemy

    rejemy

    Joined:
    Nov 1, 2013
    Posts:
    5
    Ok, another weird question about SVG Sprite meshes. Thanks again for your endless time on this thread! Sorry! :(

    Background: I'm noticing that many of the meshes I've extracted from SVG Sprites have a few backwards facing triangles mixed in here and there. Some have more than others, I think it might be related to <path> elements. The reason I care is that I was hoping to have my vector meshes be invisible from the back, so that you could see through walls that are facing away from you. I've written some code to remove backwards triangles when I extract the mesh from the sprite, and that seems to work great, at the cost of additional processing.

    The Question: are backwards facing triangles something expected and intentional, or is this a bug I should report? I have a super simple SVG that generates them that I can submit.
     
  29. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    We aimed to have all the generated triangles to be front-facing, but given that the shader doesn't have backface culling turned on, we might have missed some of them. I remember that the generated corners for the strokes were especially hard to get right.

    You should definitely report a bug for this. Please provide problematic assets as well if possible. Thanks!
     
  30. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    @nsxdavid I had a quick look on SVG + HDRP. The options are very limited at this point. I tried to get an additional render camera, configure it in "forward render" mode and enable MSAA on it. But, as you mentioned, the problem is to blend this UI camera output to the main color framebuffer.

    There may be a way to do this "soon", as there's this pull request that adds support for custom passes in HDRP:
    https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/4317

    Using a custom pass would presumably allow to blit the content of the UI camera (stored in a render texture) to the main color framebuffer.

    In the meantime, the best result I got was by having the canvas set in "Camera Space - Overlay" mode, and to use the morphological "SMAA" antialiasing method on the camera. Unfortunately, temporal antialiasing doesn't work since, as I understand it, the sprite system doesn't seem to output motion vector data.

    Please know that we're very much aware of the situation. I'll try to keep in touch regarding our antialiasing progress with SVG.
     
  31. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    341
    @mcoted3d Thank you very, very much for taking the time to look at this. And to feel our pain. Makes me feel very good that you guys are internalizing this disconnect in the feature streams. Much appreciated!
     
  32. nsxdavid

    nsxdavid

    Joined:
    Apr 6, 2009
    Posts:
    341
    I presume this would work too, but the sticky point might be doing the antialiasing on the render target texture where the UI is rendered. The post processing stack on HDRP is different in the types of buffers it can work on (very restricted or something). I'll have to figure out how to give this a try.
     
    mcoted3d likes this.
  33. MentalFish

    MentalFish

    Joined:
    Nov 2, 2005
    Posts:
    281
  34. Rosethornian

    Rosethornian

    Joined:
    Apr 26, 2018
    Posts:
    32
    Hi again @mcoted3d - I have an issue with SVG rendering on Android.

    I've been developing an app on Windows where all the SVGs render nicely but when I tried deploying it to my Android device, many of the SVGs show rendering artifacts or do not render well at all.

    Is this a known problem or is it a configuration issue?
     
  35. Apollych

    Apollych

    Joined:
    Oct 7, 2019
    Posts:
    2
    Hello!
    What is the best way to place SVG sprite to the skinned mesh (square plane) after SVGImporter?

    VectorUtils.BuildSprite then VectorUtils.RenderSpriteToTexture2D?
     
  36. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    Unfortunately, no. We did prototype a Delaunay tessellator option in the past, but we couldn't get it stable enough for production use.

    Most of the problems came from the way SVG specify "holes" in shapes using the fill rules. As far as I can tell, these rules can't be easily translated to Delaunay triangulators.

    That said, we really want to provide that kind of triangulator. They generate triangles that are more "GPU friendly" than what LibTess generates.
     
    MentalFish and Lars-Steenhoff like this.
  37. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    It's hard to tell without having the assets in hand. If you are using SVG with gradients and/or textures, there may be sampling precision issues.

    The best would be for you to file a bug report (Help > Report a Bug...), then we will look into it.
     
  38. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    I'm not sure I understand what you are trying to achieve. Do you want to apply the SVG as a texture around a skinned mesh? Or do you want to skin the actual sprite generated by the SVGImporter?

    For 1), the simplest would be to import your SVG as a "Texture2D" asset from the "Generated Asset Type" importer option. Then you can apply the texture on your skinned mesh. What you suggested (BuildSprite + RenderSpriteToTexture2D) would work as well.

    For 2), this is not supported at this time.
     
  39. Apollych

    Apollych

    Joined:
    Oct 7, 2019
    Posts:
    2
    Thank you! It's works. I am implementing flipping book page with SVG sprite on it. Page is skinned mesh.

    So, one more question from me please: There are errors in the Unity console:
    Missing Profiler.EndSample (BeginSample and EndSample count must match): GenerateAtlas
    Previous 5 samples:
    GC.Alloc
    Application.CallLogCallback()
    GC.Alloc
    logCallback.Invoke
    GC.Alloc
    In the scope:
    GenerateAtlas
    MainGameManager.Update()
    BehaviourUpdate
    Update.ScriptRunBehaviourUpdate
    PlayerLoop


    In MainGameManager.Update() I use BuildSprite and RenderSpriteToTexture. The errors don't break program execution, just annoying. If I remove "Profiler" strings from the VectorSprite.cs code they will recover next Unity load. Should I create a ticket?
     
  40. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    338
    Yes please!