First of all, thank you for purchasing this asset! You will find the most up to date version of this documentation on our website. The following document contains essential information to get you started. You can also join our Discord for quicker feedback.

Current Version 1.6.0
  • Added line charts, linear and logarithmic axes.
Older versions
  • Added code support for HDRP. (1.5.2)
  • Fixed wrong namespaces. (1.5.2)
  • Fixed Texture UV and Normal generation. Some shapes were missing UV coordinates and normals. (1.5.1)
  • Added dashed polylines. (1.5.1)
  • Added advanced grid shape. (1.4.0)
  • Added arrow shapes. (1.3.0)
  • Added rounded polygon (1.2.0)
  • Added quadrilaterals and planes (1.1.0)
  • First release: regular polygons, polylines, ellipses, rings, SVG parser (1.0.0)

You can add VectorizerFigures to your scene either via the menu GameObject/Vectorizer/Add ... or manually by creating an empty GameObject; then click on AddComponent and start typing Vectorizer...; finally choose the element you want from the list.

Every VectorizerFigure will create two child GameObjects: one representing the Stroke part of the figure (if its StrokeThickness is greater than zero), and another for the Fill.

Materials

In order to assign the material you wish to use for the figure's Stroke and Fill, remember to do so via the corresponding properties in the root GameObject.

The library provides a special URP shader (also available as a standard pipeline shader in the Shaders folder) called StrokeDepthOffset. This material applies a customisable Offset Bias to the rendered figure, to avoid Z-Fighting. In most figures, this is unnecessary. However, in some complex figures with hundreds of vertices (such as partial rings) or SVG figures (not originally designed for use in Vectorizer) the stroke might appear to overlap with the fill part. This material, when applied to the stroke, will make sure that it appears always on top.

There is also another URP shader, called TextureUV that allows you to visualise UV coordinates.

Debugging

Click on either the Stroke or Fill child GameObject you wish to debug and add a VectorizerMeshDebugger component. This will allow you to inspect the vertices, indices, and Texture coordinates of the generated figure. Built-in methods allow you to display in the Scene View which vertex or triangle the values refer to.

It also allows you to save the generated mesh to disk, by clicking on Save Asset. Files will be saved in the Assets/Vectorizer folder.

Samples

In the Assets/Vectorizer/Samples folder you will find various scenes. The Overview scenes provides an example of all the figures currently supported. The SVG Icons scene provides different examples of SVG icons rendered in Vectorizer. The SVG code for those icons comes from the Bootstrap icon library. The Texture Coordinates scene visualise how Texture coordinates are generated on various figures. The remaining scenes show various variations of the supported figures.

Stroke Thickness

Every VectorizerFigure provides object-specific properties. One that you can find in every object is the StrokeThickness. It defines, in world units, the width to use to draw the outline of the figure. If it is equal to zero, the Stroke part of the mesh will not be drawn.

Has Fill

If set to True, the Fill part of the figure will be generated (marked by VectorizerInstructions of type Fill). Otherwise, it will be ignored even if a material is assigned.

Curve Tolerance

Controls the tessellation of curved lines. The lower, the more vertices are used.

Width and Height

The width, respectively, the height of the rectangle, in world units.

Radius

Only for RoundedRectangles. Controls the radius of the rounded corners, in world units.

Note: use the VectorizerAdvancedGrid if you want a grid where you can specify both Major and Minor grid lines.

Columns and Rows

Indicates how many columns and rows the grid should have. A maximum of 65535 vertices per figure are allowed.

Cell Width

The length in units of a single (square) grid cell.

Sides

Indicates the number of sides to use to render the polygon. The higher the number, the more it will approximate a circle. If your intention is to create a circle, do use VectorizerEllipse instead. That way, you can control the figure by expressing the length of the semimajor axis.

Radius

Only for RoundedPolygon. Controls the radius of the rounded corners, in world units.

Type

Choose between TrapezoidIsosceles, TrapezoidRight/Left, Parallelogram and Rhombus.

BaseA, BaseB, and Height

Used in TrapezoidIsosceles and both TrapezoidRight/Left. BaseA and BaseB refer to the bottom and top bases, respectively. Height represents the distance between the two bases.

Rhombus uses only BaseA and Height. In this figure BaseA and Height are used to determine the total horizontal and vertical lenghts, respectively.

Parallelogram Angle

Used only for the parallelogram. Represents the angle opposite the height. In this figure, only BaseA and Height are used to determine the horizontal and vertical lengths, respectively.

Side Length

The length of each side of the polygon, in world units.

Columns and Rows

Indicates how many quads the fill area should have. A maximum of 65535 vertices per figure are allowed.

Tessellation

Indicates the number of sides to use to render the polygon. Use at least 32 vertices to approximate a circle.

Semimajor and Semiminor axes

The semimajor axis is equivalent to the radius of a circle, when both its semi-major and semi-minor axes are equal. If they are different, an ellipse will be rendered.

Points

The number of points the star should have.

Inner and Outer radius

Imagine the star as two circles. The Outer radius represents the radius of the circle touching all the points of the star (the circumscribing circle). The Inner radius represents the radius of the circle inscribed within the star.

Tessellation

Indicates the number of sides to use to render the polygon. Use at least 32 vertices to approximate a circle.

Outer and Inner Semimajor axis

Represents the length of the semimajor axis for the outer part and inner part. The length of inner semimajor axis cannot be greater than the outer semimajor axis.

Eccentricity

The Eccentricity controls the shape of the Ellipse. Use 0 for a circle, and a value between >0 and <1 for an Ellipse.

From and To Angles

Represent the amplitude of the starting and final angle of a partial disk, expressed in degrees. If these correspond to 0 and 360, the ring will be whole.

Clockwise

The direction to use when deciding the direction of the angles.

Cap Ends

Whether or not to cap the outline of a partial ring. Has no effect on whole rings.

Points

A vector containing the coordinates of the polyline's vertices. For a more user friendly way of entering these vertices, consider extending VectorizerPolyline and changing the contents of the Points property.

Line Style

How to render the joints of the polyline, between Miter, Round, and Bevel.

Radius

Controls the radius of the rounded joints, in world units. Only relevant for the Round Line Style.

Closed

If True an additional segment will be added, connecting the last point to the first.

Points

A vector containing the coordinates of the polyline's vertices. For a more user friendly way of entering these vertices, consider extending VectorizerPolyline and changing the contents of the Points property.

Dash Style

A vector containing alternating lengths for dashes and gaps. The array length must be a multiple of 2, its components must be positive and non-zero. The 0th element in the array represents the length of the first dash in world units, the 1st element, the length of the first gap. If a 3rd and 4th elements (or more) are present, then they will represent the length of the second dash and second gap in the series, and so on, alternating until the segment is rendered.

Min Dash Length

The minimum length of a (filled) dash that can be rendered.

Closed

If True an additional segment will be added, connecting the last point to the first.

Data

A string representing valid SVG path syntax. I.e. the part in the d attribute of an SVG Path element.

Base width and height

With an arrow pointing north, the base width refers to the length of the base of the arrow's body or rectangular part, and the height as its length.

Arrow width and height

The width and height refer to the length of the base of the triangular part, respectively its height.

Linear Chart

The Linear Chart object is a set of different objects: two axes, a background, and the line itself. You can change the individual properties of these objects by accessing them directly. You can set the points by accessing the Data property of the VectorizerLinearChart object.

See the Samples/Charts scene for a demonstration.

VectorizerFigures are essentially just meshes. Simple icon-like graphics will likely have very few vertices, and therefore the performance will be negligible on modern GPUs. Round figures such as circles, ellipses, paths with Bézier curves, etc. will instead need several vertices, but are still well within the capabilities of modern hardware. You can control the tessellation of these figures via the object's properties. In more extreme cases, you can consider saving the generated meshes as an asset via the built-in Save Asset feature of the VectorizerMeshDebugger component.

When I load one of the sample scenes, the editor complains about a missing script on the Camera GameObject. How do I fix it?

Importing errors have been reported. It is most likely related to the script SimpleCameraController. You can simply reattach it to the Camera GameObject by removing the missing component warning (click on the three dots icon next to it, select Remove Component) then click on Add Component and type SimpleCameraController. You can find it in the Assets/Vectorizer/Samples/Scripts folder.

Why is part of my figure not rendering correctly? Some parts flash in and out.

That is Z-Fighting. It happens because some triangles overlap others (they are on the same plane). And the GPU does not know which one should be on top. In the case of VectorizerPath, make sure no part overlaps itself, by changing the StrokeThickness for example). Otherwise, you can assign the Stroke Depth Offset material to the part of the figure you wish to always make appear on top (e.g., the stroke). Make sure you assign it to Material slot in the root GameObject, and not to the Material slot in the generated child GameObjects. You can find this material in the Assets/Vectorizer/Materials folder.

The VectorizerPath is not displaying correctly. It does not look the same as when rendered in a HTML5 canvas.

In general, SVG figures are not designed around the limitations of 3D mesh vertices. This means that in a software like Adobe Illustrator or other vector graphics design environments, it is not usually a problem if parts of a figure overlap themselves. In Vectorizer, these circumstances might affect how the figure is displayed. If it does not look correct, try splitting the figure in multiple elements, and/or specifying the vertices in counter-clockwise order. Especially if your figure is concave rather than convex.

Does Vectorizer support the SVG fill-rule attribute?

Currently, there is no support for the SVG fill-rule attribute. This means these figures should be split into multiple VectorizerPath objects. See the SVG Icons sample for examples.

How do I create custom VectorizerFigures?

You need to derive from VectorizerFigure and implement two methods: Rebuild and Validate. Let's look at an example:

    [ExecuteInEditMode]
    [RequireComponent(typeof(VectorizerMesh))]
    public class VectorizerEllipse : VectorizerFigure
    {
        [Range(3f, 320f)]
        public int Tessellation = 32;

        [Range(0.001f, 256f)] public float SemiMajorAxis = 8;
        [Range(0.001f, 256f)] public float SemiMinorAxis = 8;

        public override void Rebuild()
        {
            // This function is called every time the parameters change.
            // Therefore, we need to clear the instructions having old values.
            Designer.ClearInstructions();

            // We add a new Fill Ellipse instruction based on the current values.
            // To avoid an overlap between the interior part and the outline,
            // we reduce the length of the semi-major and semi-minor axis
            // by half the stroke thickness' width.
            Designer.AddInstruction(new FillEllipse(Tessellation, SemiMajorAxis-StrokeThickness/2,
                SemiMinorAxis - StrokeThickness / 2));

            // If this figure has a stroke part (HasStroke), then we 
            // need to add the corresponding instructions.
            if (HasStroke)
            {
                Designer.AddInstruction(new DrawEllipse(Tessellation, SemiMajorAxis, SemiMinorAxis,
                    strokeThickness:StrokeThickness));
                
                // This instruction makes sure that the vertices belonging to the
                // interior area have the same exact values as those on the outline,
                // to account for floating-point errors.
                Designer.AddInstruction(new WeldPolygonVerticesInstruction());
            }
        }

        protected override bool Validate()
        {
            // return true when the figure is valid according to the current
            // value of the parameters.
            return SemiMajorAxis >= 0.01f && SemiMinorAxis >= 0.01f;
        }

        // To make your figure appear in the menu, implement a similar function
        [MenuItem(VectorizerMenu.GameObject + "Ellipse")]
        public static void CreateEllipse() { Create<VectorizerEllipse>(); }
    }

Will Vectorizer implement X Y Z in a future release?

I am happy to expand Vectorizer's features. Please contact me to discuss your suggestion.