Unity中关于Vector Graphics的内容(帮助翻译)

关于Vector Graphics

        Vector Graphics package提供了一个SVG导入器以及通用的矢量图形API。

        该包被认为是实验性的,不建议在生产中使用。因此,必须使用Unity Package Manager manualUnity Package Manager manual中描述的com.unity.vectorgraphics名称来添加包。

要求

        Vector Graphics package版本1.0.0与以下版本的Unity编辑器兼容: 2018.1及更高版本。

已知限制

        Vector Graphics package中的SVG导入器实现了SVG 1.1规范的一个子集,但有一些限制:

  • 文本元素还不受支持(SVG 1.1第10节)
  • 不支持逐像素遮罩(SVG 1.1第14.4节)
  • 不支持过滤器效果(SVG 1.1第15节)
  • 不支持任何交互性特性(SVG 1.1第16节)
  • 不支持动画(SVG 1.1第19节)

        请注意,当使用-no-graphics命令行参数启动Unity时,程序包可能无法正确导入资产。该包在以纹理格式导入资产时需要图形,因为它将需要将向量内容呈现到纹理资产中。

使用Vector Graphics

SVG导入器

        这个包提供了一个SVG导入器,可以读取和解释SVG文档,并生成在Unity中使用的2D精灵。

像其他资产一样将SVG文件导入Unity编辑器。

        将它们直接放到“项目”窗口的“资产”文件夹中,或者从菜单栏中选择“Assets > Import New Asset”。导入后,您可以在层次结构视图或场景视图中实例化结果资产。

属性功能
Pixels Per Unit对应于1个场景单元的SVG单元数。
Tessellation Step Distance

当创建路径时,Unity生成三角形的距离。

较小的步长将导致更光滑的曲线,但代价是更多的三角形。

Gradient Resolution用于存储渐变的纹理大小。
Pivot

所生成的精灵的轴心的位置。这遵循与常规精灵相同的约定,并有一个额外的SVG Origin值。当使用SVG Origin时,轴心是(0,0)。

基础设置

 当Setting使用Basic参数时,只需要提供目标分辨率(Target Resolution)和缩放因子(Zoom Factor)。当Setting使用Advanced参数时,可确保您的SVG文档渲染在足够高的分辨率。

高级设置 

​ 

如果要全面控制SVG文档的导入,则可以指定以下高级设置: 

属性功能
Step Distance

导入器沿着路径生成顶点时所处的距离。较低的值会导致更密集的网格。

Sampling Steps

导入器根据路径进行计算的样本数。更多的样本可能会得到更精确的曲线,特别是当曲线有尖角时。

Max Cord Deviation最大直线偏差,较小的值产生更多的网格。
Max Tangent Angle导入器生成网格的最大切线角度(单位是度)。

​ 

        只要不满足每个已启用的约束,导入器就会对曲线进行细分。

        精灵编辑器也可用,其工作方式与常规的精灵资源完全相同。

Vector Graphics API

        所提供的类和方法使您能够直接在代码中处理向量数据。

        SVG导入器在内部使用这些api来生成和细分生成的精灵。

        向量图形API是一组简单的类和结构,它将向量数据保存在一起。

        这是伴随着静态的方法来操作和转换这些数据。

        向量图形包的核心是场景类(Scene),它存储了一个向量对象的图形。

        它的根属性(Root)是场景节点(SceneNode)的一个实例,它包含可绘制项列表、子节点列表、转换和剪切器(请参见后面的剪切部分内容)。

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; }
}

主要有两种可绘制的实例:路径(Paths)和形状(Shapes)。

Paths 

        路径是由BezierContour线定义的可绘制路径。BezierContour包含BezierPathSegment数组和指示轮廓是否关闭的标志。

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;
}

        BezierPathSegment数组定义了一个三次Bézier曲线链。上面的线段只指定第一个点P0和两个控制点P1和P2。路径类(Path)使用数组中下一个段的P0值来完成曲线。因此,您总是需要至少两个段来定义一个有效的BezierContour。使用这种方法允许链接多个线段,并保证曲线的连续性。例如,考虑此路径:

        你可以这样构建这个路径:

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 }
	}
};

        当定义具有Closed = true的BezierContour时,轮廓的最后一个路径段将被连接到第一个路径段,并且最后一个路径段的P1和P2值将被用作控制点。

Shapes

        就像路径一样,形状也是由BezierContour定义的,但它们也提供了一种填充方法:

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; }
}

        有几个类实现了IFill接口:

  • SolidFill 一个简单的彩色填充
  • TextureFill纹理填充
  • GradientFill 线性或径向渐变填充

 Gradients

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; }
}

        请考虑以下线性填充,以及要生成它的GradientFill实例:

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 }
	}
};

         梯度寻址模式定义了当梯度坐标超出范围时,Unity如何显示颜色,如下图所示:

Fill Mode 

        填充类还提供了一个填充模式,它决定了如何定义形状内部的孔。

        FillMode.NonZero通过将轮廓段与水平线相交来确定哪些点在一个形状内。轮廓的方向确定点是在形状内部还是外部:

 

        FillMode.OddEven还可以通过将分段与一条水平线相交来工作。形状内的点是偶数段交叉时的点,奇数段交叉时,形状外的点:

 

Clipping 

        在上面的例子中,重复的正方形形状被一个椭圆剪切。在代码中,这可以这样做:

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
};

        请注意,只有形状可以作为剪裁器(剪裁过程会忽略在剪裁器中定义的任何笔划)。被剪辑的内容可以是任何形状和/或笔画。

        警告:剪切过程可能是一个昂贵的操作。使用简单剪切简单形状可能执行合理,但任何复杂形状和/或剪裁都可能导致帧率显著下降。

渲染矢量图形 

        要在屏幕上渲染矢量图形元素,首先获取场景的镶嵌(三角)版本。当设置了矢量场景实例时,可以使用以下VectorUtils方法对其进行细分:

public static List<Geometry> TessellateScene(Scene scene, TesselationOptions options);

 TesselationOptions类似于高级导入器设置: 

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

        请注意,最大的角度偏差(maxTanAngleDeviation)是用弧度表示的。

        若要禁用最大测线偏差约束(maxCordDeviation),请将其设置为float.MaxValue。

        要禁用最大的偏差约束(maxTanAngleDeviation),请将其设置为Mathf.PI/2.0f。

        禁用约束将使镶嵌速度加快,但可能会生成更多的顶点。

        几何体(Geometry)对象的结果列表包含正确渲染场景所需的所有顶点和相关信息。

纹理和渐变图谱 

        如果场景具有任何纹理或渐变,则必须生成纹理图集并填充几何图形的UV。这些方法是向量数类(VectorUtils)的一部分: 

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

        GenerateAtlas方法是一项昂贵的操作,因此尽可能缓存生成的纹理2D对象。仅当场景内的纹理或渐变发生变化时,才需要重新生成图集。

        当顶点在几何体内部发生变化时,请调用FillUVs方法。绘制镶嵌场景您可以通过多种方式渲染几何图形。例如:

  • 填充Mesh资产
  • 建立一个Sprite资产
  • 使用Unity的低级图形库 

        对于这些方法,使用任何一种提供的材料来绘制镶嵌矢量图形内容。如果场景包含纹理或渐变,请使用以下材质:

var mat = new Material(Shader.Find("Unlit/VectorGradient"));

        否则,你可以使用:

var mat = new Material(Shader.Find("Unlit/Vector"));

        要填充网格资源,请使用以下“VectorUtils”方法:

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

        要构建精灵资源,请使用以下VectorUtils类型方法: 

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

        要将精灵渲染到Texture2D,请使用以下VectorUtils方法:

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

        要使用即时模式GL命令渲染生成的精灵,请使用VectorUtils类中的“RenderSprite”方法将精灵绘制成一个单位方块(X和Y方向上0和1之间的框):

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值