[Unity] Vector Graphics -使用 SVG矢量图

[2.0.0-preview.13] Vector Graphics
unity 支持 使用 SVG 矢量图,使用sprite的格式,UI 使用 SVGImage

Using Vector Graphics
SVG importer
This package provides an SVG importer that reads and interprets SVG documents and generates 2D sprites for use in Unity.

You import SVG files into the Unity Editor like any other assets. Either drop them directly into the Assets folder in the Projects window, or select Assets > Import New Asset from the menu bar. When imported, you can instantiate the resulting assets in the Hierarchy View or the Scene View.

Property Function
Pixels Per Unit Number of SVG units that correspond to 1 scene unit.
Tessellation Step Distance Distance at which Unity generates triangles when tessellating the paths. A smaller step distance will result in smoother curves at the expense of more triangles.
Gradient Resolution Texture size used to store gradients.
Pivot Location of the pivot for the generated sprite. This follows the same convention as regular sprites, with an additional SVG Origin pivot value. When using SVG Origin, the pivot is the (0,0) position of the SVG document.
You can provide tessellation settings in two ways: Basic or Advanced.

Basic tessellation
SVG importer properties

When using Basic, you only need to provide a Target Resolution and a Zoom Factor. Then the importer automatically configures the advanced settings to make sure your SVG document renders at a high enough tessellation for that resolution at that zoom factor.

Advanced tessellation
SVG importer properties

If you want full control over the tessellation of the SVG document, you can specify the following advanced settings:

Property Function
Step Distance Distance at which the importer generates vertices along the paths. Lower values result in a more dense tessellation.
Sampling Steps Number of samples the importer evaluates on paths. More samples may result in more precise curves, especially when the curves have sharp corners.
Max Cord Deviation Distance on the cord to a straight line between two points after which the importer generates more tessellation.
Max Tangent Angle Maximum tangent angle (in degrees) after which the importer generates tessellation.
Max Cord

The importer subdivides curves for as long as every enabled constraint isn’t satisfied.

The Sprite Editor is also available and works exactly the same way as regular sprite assets.

Vector Graphics API
The provided classes and methods enable you to work with vector data directly in code. The SVG importer uses these APIs internally to generate and tessellate the resulting sprites.

The Vector Graphics API is a set of simple classes and structures that holds the vector data together. This is accompanied by static methods to manipulate and transform this data.

At the core of the Vector Graphics package is the Scene class, which stores a graph of vector objects. Its Root property is an instance of SceneNode, which contains a list of drawable items, a list of child nodes, a transform and a clipper (see clipping).

public class SceneNode
{
    public List<SceneNode> Children { get; set; }
    public List<IDrawable> Drawables { get; set; }
    public Matrix2D Transform { get; set; }
    public SceneNode Clipper { get; set; }
}

There are two main kind of drawable instances: paths and shapes.

Paths
Paths are drawables that are defined by a BezierContour. A BezierContour contains a BezierPathSegment array and a flag that indicates whether the contour is closed or not.

public class Path : IDrawable
{
    public BezierContour Contour { get; set; }
    public PathProperties PathProps { get; set; }
}

public struct BezierContour
{
    public BezierPathSegment[] Segments { get; set; }
    public bool Closed { get; set; }
}

public struct BezierPathSegment
{
    public Vector2 P0;
    public Vector2 P1;
    public Vector2 P2;
}

The BezierPathSegment array defines a chain of cubic Bézier curves. The above segment specifies only the first point, P0, and two control points, P1 and P2. The Path class uses the P0 value of the next segment in the array to complete the curve. So, you will always need at least two segments to define a valid BezierContour. Using this approach allows the chaining of multiple segments and guarantees the continuity of the curve. For example, consider this path:

Contour

You could construct this path like so:

var segments = new BezierPathSegment[] {
    new BezierPathSegment() { P0 = a, P1 = b, P2 = c },
    new BezierPathSegment() { P0 = d, P1 = e, P2 = f },
    new BezierPathSegment() { P0 = g }
};

var path = new Path() {
    contour = new BezierContour() {
        Segments = segments,
        Closed = false
    },
    pathProps = new PathProperties() {
        Stroke = new Stroke() { Color = Color.red, HalfThickness = 1.0f }
    }
};

When defining a BezierContour with Closed = true, the contour’s last path segment will be connected to the first path segment, and the last path segment’s P1 and P2 values will be used as control points.

Shapes
Just like paths, shapes are defined by a BezierContour, but they also provide a filling method:

public class Shape : Filled
{
    public BezierContour[] Contours { get; set; }
}

public abstract class Filled : IDrawable
{
    public IFill Fill { get; set; }
    public Matrix2D FillTransform { get; set; }
    public PathProperties PathProps { get; set; }
}

Several classes implement the IFill interface:

SolidFill for a simple colored fillings
TextureFill for a texture fillings
GradientFill for linear or radial gradient fillings
Gradients
Gradient fills are defined by a Linear or Radial type and a series of colors/percentage pairs, called stops:

public class GradientFill : IFill
{
    public GradientFillType Type { get; set; }
    public GradientStop[] Stops { get; set; }
    public FillMode Mode { get; set; }
    public AddressMode Addressing { get; set; }
    public Vector2 RadialFocus { get; set; }
}

public struct GradientStop
{
    public Color Color { get; set; }
    public float StopPercentage { get; set; }
}
Consider the following linear fill, as well as the GradientFill instance to generate it:

Linear Fill

var fill = new GradientFill() {
    Type = GradientFillType.Linear,
    Stops = new GradientFillStop[] {
        new GradientFillStop() { Color = Color.blue, StopPercentage = 0.0f },
        new GradientFillStop() { Color = Color.red, StopPercentage = 0.5f },
        new GradientFillStop() { Color = Color.yellow, StopPercentage = 1.0f }
    }
};

The gradient addressing modes define how Unity displays the color when the gradient coordinates fall outside of the range, as illustrated here:

Addressing Modes

Fill Mode
The filling classes also provide a fill mode, which determines how holes are defined inside the shapes.

FillMode.NonZero determines which points are inside a shape by intersecting the contour segments with an horizontal line. The direction of the contour determines whether the points are inside or outside the shape:

NonZero Fill

FillMode.OddEven also works by intersecting the segments with an horizontal line. Points inside the shape occur when an even number of segments is crossed, and points outside the shape occur when an odd number of segments is crossed:

EvenOdd Fill

Clipping
The SceneNode class has a clipper member which will clip the content of the node.

Clipper

In the above example, the repeating square shapes are clipped by an ellipse. In code, this can be done like so:

var ellipse = new SceneNode() {
    Drawables = new List<IDrawable> { VectorUtils.MakeEllipse(ellipse, Vector2.zero, 50, 100) }
};

var squaresPattern = ...;

var squaresClipped = new SceneNode() {
    Children = new List<SceneNode> { squaresPattern },
    Clipper = ellipse
};

Note that only shapes can act as a clipper (the clipping process ignores any strokes defined in the clipper). The content being clipped can be any shapes and/or strokes.

Warning: The clipping process can be an expensive operation. Clipping simple shapes with a simple clipper may perform reasonably, but any complex shape and/or clipper may cause the frame rate to drop significantly.

Rendering vector graphics
To render vector graphics elements on screen, first get a tessellated (triangulated) version of the scene. When you have a VectorScene instance set up, you can tessellate it using the following VectorUtils method:

public static List TessellateScene(Scene scene, TesselationOptions options);
The TesselationOptions are similar to the advanced importer settings:

public struct TesselationOptions
{
    public float StepDistance { get; set; }
    public float MaxCordDeviation { get; set; }
    public float MaxTanAngleDeviation { get; set; }
    public float SamplingStepSize { get; set; }
}

Note that maxTanAngleDeviation is specified in radians.

To disable the maxCordDeviation constraint, set it to float.MaxValue. To disable the maxTanAngleDeviation constraint, set it to Mathf.PI/2.0f. Disabling the constraints will make the tessellation faster, but may generate more vertices.

The resulting list of Geometry objects contains all the vertices and accompanying information required to render the scene properly.

Textures and gradients atlases
If the scene has any textures or gradients, you will have to generate a texture atlas and fill the UVs of the geometry. These methods are part of the VectorUtils class:

public static TextureAtlas GenerateAtlas(
    IEnumerable<Geometry> geoms, // The geometry generated by the TessellateScene method
    uint rasterSize);            // The desired atlas size (128 is enough for most purposes)

public static void FillUVs(
    IEnumerable<Geometry> geoms, // The geometry for which the UVs will be filled
    TextureAtlas texAtlas);      // The texture atlas generated by the 

GenerateAtlas method
The GenerateAtlas method is an expensive operation, so cache the resulting Texture2D object whenever possible. You only need to regenerate the atlas when a texture or gradient changes inside the scene.

When vertices change inside the geometry, call the FillUVs method, which is cheap. Drawing a tessellated scene You can render the geometry in several ways. For example:

Filling a Mesh asset
Building a Sprite asset
Using Unity’s low level graphics library
For any of these methods, use the provided materials to draw the tessellated vector graphics content. If the scene contains textures or gradients, use the following material:

var mat = new Material(Shader.Find("Unlit/VectorGradient"));
Otherwise, you can use:

var mat = new Material(Shader.Find("Unlit/Vector"));
To fill a mesh asset, use the following VectorUtils method:

public static void FillMesh(
    Mesh mesh,               // The mesh to fill, which will be cleared before filling
    List<Geometry> geoms,    // The geometry resulting from the "TessellateScene" call
    float svgPixelsPerUnit,  // How many "SVG units" should fit in a "Unity unit"
    bool flipYAxis = false); // If true, the Y-axis will point downward
To build a sprite asset, use the following VectorUtils method:

public static Sprite BuildSprite(
    List<Geometry> geoms,       // The geometry resulting from the "TesselateScene" call
    float svgPixelsPerUnit,     // How many "SVG units" should fit in a "Unity unit"
    Alignment alignment,        // The sprite alignement
    Vector2 customPivot,        // If alignment is "Custom", this will be used as the custom pivot
    UInt16 gradientResolution); // The resolution used for the gradient texture
To render a sprite to a Texture2D, use the following VectorUtils method:

public static Texture2D RenderSpriteToTexture2D(
    Sprite sprite,          // The sprite to draw
    int width, int height,  // The texture dimensions
    Material mat,           // The material to use (should be Unlit_Vector or Unlit_VectorGradient)
    int antiAliasing = 1);  // The number of samples per pixel

To render the generated sprite using immediate mode GL commands, use the RenderSprite method in the VectorUtils class to draw the sprite into a unit square (a box between 0 and 1 in both X and Y directions):

public static void RenderSprite(
    Sprite sprite,  // The sprite to draw
    Material mat);  // The material to use (should be Unlit_Vector or Unlit_VectorGradient)

你可能感兴趣的:(Unity,unity,svg)