Skip to content

Latest commit

 

History

History
263 lines (201 loc) · 18.3 KB

README.md

File metadata and controls

263 lines (201 loc) · 18.3 KB

Godot SVG

This Godot 4.3 plugin renders SVG files at runtime. It achieves the effect of infinite scaling and smooth curves by calculating the curves in shaders drawn on polygons.

To be clear, Godot already has built-in functionality to import SVGs and display them as rasterized (pixel map) textures in-game. This is likely what you should do 90% of the time instead of using this plugin to render every SVG in your game.

Alpha Testing Caveats

This software is in early development.

  1. If your SVG has self-intersecting paths, you may see visual bugs. There is a lot of code written to solve this scenario, but it is still being worked on and there are many W3C test suite examples where it is known to not work.

  2. You may run into a problem where loading certain SVG files causes Godot to freeze, due to the path solver getting stuck in an infinite loop. To prevent this, don't use SVGs with self-intersecting paths or thin strokes.

  3. Check the support table at the bottom before reporting bugs.

Godot Core Issues

Resolving the following issues in Godot core will improve this plugin. Please visit them and give a thumbs up.

  1. Expose _edit_get_rect, _edit_use_rect to gdscript - SVG2D is set up as a custom node, without this engine feature you cannot resize and rescale it with editor controls (must use the inspector).

Installation

Copy the addons/godot-svg folder in this repository into your Godot project. Make sure the folder sits exactly at the path res://addons/godot-svg. If you put it somewhere else, some things like icons may break.

In Godot, go to Project -> Project Settings -> Plugins and check the Enable checkbox.

Usage

  1. When importing a SVG into Godot, it defaults to "Import As: Texture". Change this dropdown to "Import As: SVG", then re-import.

Visual instructions


  1. Now in a 2D scene, add a SVG2D node. Drag & drop your SVG file to the "SVG" property of this node, and you will see the SVG rendered in realtime!

Visual instructions

SVG2D & SVGRect Documentation

These nodes share a similar API.

The SVG2D Node:

Use in 2D scenes similar to how you would use a Sprite. The default size of the SVG2D is determined by the viewBox, width, and height attributes on the imported <svg> element.

The SVGRect Node:

Use in 2D scenes similar to how you would use a TextureRect. How the SVG fits inside of this rectangle is determined by the preserveAspectRatio attribute on the imported <svg> element.

Note: If you use any undocumented methods or properties, you risk your code breaking in any future update.

PROPERTIES

Property Name Value Type Notes
svg SVG Resource When importing a SVG file, choose "Import As: SVG". If you try to add a SVG imported as "Texture" here, it will not work. Use Sprite instead for that.
fixed_scaling_ratio float [This feature may not yet be working as expected]. Setting the value above 0 bakes the resolution of masks so they are not redrawn due to scaling at runtime. A value of 1 means it is drawn to look perfect at 100% view box scale (1:1), and if you zoom in further than that you will see pixellated edges. Setting the value to 0 redraws the mask every frame.
antialiased bool Whether or not to use the antialiasing to smooth the shape edges.
triangulation_method SVGValueConstant.
TriangulationMethod
Delaunay and Earcut are two different triangulation methods used to fill the interior of the shape. Their accuracy and performance characteristics vary based on the situation. Generally Earcut is faster but less accurate.
assume_no_self_intersections bool This is an optimization that can make the initial construction/animation of the shape faster by not even attempting to solve for self-intersecting shapes. If there are actual intersections, the shape may not draw or may have rendering artifacts.
assume_no_holes bool This is an optimization that can make the initial construction/animation of the shape faster by not even attempting to solve for holes. If there are potential holes, they are ignored.
disable_render_cache bool When you first load a SVG in the editor, it will spend time solving and triangulating the paths. This solution is saved back to the asset for a faster load time. This property disables that process.

METHODS

Method Signature Notes
get_element_by_id(id: String) -> Dictionary Finds the SVG element with the given id attribute. If the node is found, a dictionary is returned in the format { "node": SVGElement2D or SVGElement3D, "resource": SVGResourceElement }. If not found, null is returned.
get_elements_by_name(name: String) -> Array Finds all SVG elements with the given tag/node name. An array containing dictionaries is returned, each dictionary in the format { "node": SVGElement2D or SVGElement3D, "resource": SVGResourceElement }. An empty array is returned if nothing is found.
load_svg_from_buffer(buffer: PoolByteArray) Loads a SVG on the fly. This is not a good idea for complex SVGs as it blocks the main thread. If you have the SVG contents as a string, you can use String.to_utf8() to convert it to a PoolByteArray.

SVGElement2D Documentation

SVGElement2D is returned from SVG2D methods such as get_element_by_id or get_elements_by_name. It represents a single element (e.g. shape, etc.) in the SVG document.

Note: If you use any undocumented methods or properties, you risk your code breaking in any future update.

METHODS

Method Signature Notes
remove_attribute(name: String) Removes an attribute with the specified name.
set_attribute(name: String, value: String) Sets the value of an attribute with the specified name. It is recommended at the moment to pass a string value, equivalent to what you would type in a SVG document.

SVG3D Documentation

While a SVG3D node exists, this is purely experimental at the moment, and you can expect it to have breaking changes in the future.

The main problem with this node at the moment is Godot doesn't provide an easy way to accurately sort transparent 3D meshes.

Performance Considerations

SVGs vs Sprites

Godot is generally much faster at drawing raster textures in 2D. Whenever you can get away with it, you should prefer using Sprites with images imported as "Texture" instead of SVGs.

Scaling

If your game uses a lot of scaling operations, and you use special features such as masks and patterns that need to be recalculated during re-scale, consider setting fixed_scaling_ratio to a value above 0.

Masks and Clip Paths

Using masks and clip paths can quickly bring your game to a crawl. Both are rasterized to the game's output resolution before being applied to shapes. This means mask performance is resolution dependent. A masked shape that takes up the entire screen will take exponentially more time to draw than a smaller masked shape that takes up half the screen.

Setting opacity < 1 on group (<g>) elements is also treated like a mask.

Stylesheets

Avoid SVGs that use stylesheets like the plague. (e.g. avoid the <style> element). It is technically supported, but it is very expensive to compute up-front. Set inline attributes instead; the inline style attribute (e.g. <rect style="fill:red">) is OK to use.

Animation

[Note: svg animation not yet implemented] Animating styling attributes that cause the shape of an element to change (such as stroke-dasharray, d, r) will cause the entire shape to be recalculated which can become expensive on a large scale. Animating masked or clip-path shapes regenerates viewport textures on the CPU each frame, which is even more expensive.

Basic Shapes

There is a performance benefit to using basic shapes (circle, ellipse, rect, line) as opposed to generating the same shape using a path, polygon, or polyline. With the latter, the shapes must be simplified first and have expensive calculations to determine the fill rule.

Support Table

ELEMENTS

Name Support Level Notes
a Status Not Yet Supported
altGlyph Status Will Not Support Deprecated
altGlyphDef Status Will Not Support Deprecated
altGlyphItem Status Will Not Support Deprecated
animate Status Not Yet Supported
animateMotion Status Not Yet Supported
animateTransform Status Not Yet Supported
circle Status Supported
clipPath Status Supported
color-profile Status Will Not Support Deprecated
cursor Status Will Not Support Deprecated
defs Status Supported
desc Status Supported Not rendered
ellipse Status Supported
feBlend Status Not Yet Supported
feColorMatrix Status Not Yet Supported
feComponentTransfer Status Not Yet Supported
feComposite Status Not Yet Supported
feConvolveMatrix Status Not Yet Supported
feDiffuseLighting Status Not Yet Supported
feDisplacementMap Status Not Yet Supported
feDistantLight Status Not Yet Supported
feFlood Status Not Yet Supported
feFuncA Status Not Yet Supported
feFuncB Status Not Yet Supported
feFuncG Status Not Yet Supported
feFuncR Status Not Yet Supported
feGaussianBlur Status Not Yet Supported
feImage Status Not Yet Supported
feMerge Status Not Yet Supported
feMergeNode Status Not Yet Supported
feMorphology Status Not Yet Supported
feOffset Status Not Yet Supported
fePointLight Status Not Yet Supported
feSpecularLighting Status Not Yet Supported
feSpotLight Status Not Yet Supported
feTile Status Not Yet Supported
feTurbulence Status Not Yet Supported
filter Status Not Yet Supported
font Status Will Not Support Deprecated
font-face Status Will Not Support Deprecated
font-face-format Status Will Not Support Deprecated
font-face-name Status Will Not Support Deprecated
font-face-src Status Will Not Support Deprecated
font-face-uri Status Will Not Support Deprecated
foreignObject Status Will Not Support No use case
g Status Supported
glyph Status Will Not Support Deprecated
glyphRef Status Will Not Support Deprecated
hkern Status Will Not Support Deprecated
image Status Supported Image href must be a relative URL pointing to an image you placed in the project under res://.
line Status Supported
linearGradient Status Supported
marker Status Not Yet Supported
mask Status Supported
metadata Status Not Yet Supported
missing-glyph Status Will Not Support Deprecated
mpath Status Not Yet Supported
path Status Supported
pattern Status Supported
polygon Status Supported
polyline Status Supported
radialGradient Status Supported
rect Status Supported
script Status Will Not Support No use case
set Status Not Yet Supported
stop Status Supported
style Status Partial Support Currently element, id, class, descendant selectors are recognized
svg Status Supported
switch Status Not Yet Supported
symbol Status Not Yet Supported
text Status Not Yet Supported
textPath Status Not Yet Supported
title Status Supported Not rendered
tref Status Will Not Support Deprecated
tspan Status Not Yet Supported
use Status Supported
view Status Not Yet Supported
vkern Status Will Not Support Deprecated

CORE ATTRIBUTES

Name Support Level Notes
id Status Supported
lang Status Not Yet Supported
tabindex Status Will Not Support No use case

STYLING ATTRIBUTES

Name Support Level Notes
class Status Supported
style Status Supported

CONDITIONAL PROCESSING ATTRIBUTES

Name Support Level Notes
requiredExtensions Status Not Yet Supported
requiredFeatures Status Will Not Support Deprecated
systemLanguage Status Not Yet Supported

PRESENTATION ATTRIBUTES

Name Support Level Notes
clip-path Status Supported Currently supported at the SVG1.1 spec
clip-rule Status Supported Currently supported at the SVG1.1 spec
color Status Partial Support Not fully tested
color-interpolation Status Partial Support Linear interpolation is implemented on gradients.
color-rendering Status Not Yet Supported
cursor Status Not Yet Supported
display Status Not Yet Supported
fill Status Supported
fill-opacity Status Supported
fill-rule Status Supported
filter Status Not Yet Supported
mask Status Supported Currently supported at the SVG1.1 spec
opacity Status Supported
pointer-events Status Not Yet Supported
shape-rendering Status Not Yet Supported
stroke Status Supported
stroke-dasharray Status Supported
stroke-dashoffset Status Supported
stroke-linecap Status Supported
stroke-linejoin Status Supported SVG2 spec "arcs" not yet implemented
stroke-miterlimit Status Supported
stroke-opacity Status Supported
stroke-width Status Supported
transform Status Supported 3D transforms are converted to 2D transforms
vector-effect Status Not Yet Supported
visibility Status Supported