Suppose I have a bunch of 2D art in some vectorized format such as SVG. Is there an easy-ish way to render that directly without having to implement a full SVG renderer myself?
Of course I could rasterize it off-line (e.g. in the content pipeline) for different resolutions/zoom levels, but I would like to maintain the crisp visuals at continuous zoom levels that vector graphics offer.
Answer
A good question. I was experimenting with this at one point - I couldn't find a easy, pre-built solution. But let me point you to some of the resources I found when attempting to implement it myself:
First of all there's an article from GPU Gems 3: Rendering Vector Art on the GPU (and the associated Loop-Blinn paper).
The hardest part is that, while drawing quadratic curves are easy, cubic curves (like those found in your typical SVG) are considerably harder. The article goes into detail on this, but you'll need to bring your maths hat.
The alternative to rendering cubic curves is to convert the cubic curves to quadratic ones. Also a non-trivial problem.
Once you can render vector curves on the GPU, it's a simple matter of parsing the SVG in your content pipeline and turning it into a mesh that you can render. Parsing SVG is easy, by the way.
Another, potentially easier alternative is to forego curves all together and simply triangulate a linear approximation of your SVG.
Both these solutions require triangulation - here's a reasonable triangulator suited to XNA.
As a completely different alternative, you can use a "distance field" to render sprites with nearly-vector-like sharp edges.
Here is a paper from Valve from SIGGRAPH 2007 on how to do this: Improved Alpha-Tested Magnification for Vector Textures and Special Effects (PDF)
The basic method here is very easy to implement. The difficulty comes when trying to make it support sharp corners (something only touched on in the paper). This method also has some pretty severe limitations for anything but drawing simple shapes. It's best suited to UI text and decals (like Valve is using it for).
Now that I've said all that - I have to say that, in my experience, all the effort here is not worth it!
Unless your gameplay is going to be based primarily around extreme vector zooming effects like the very cool Masagin demo, you can get away with pre-rendering your SVG and simply using bitmap techniques (easier, better supported, etc).
(One of the first techniques that comes to mind is mipmapping (wiki) high-resolution versions of your sprites, to give you resolution independence up until your maximum sprite size.)
This blog post is probably a good place to get started adding SVG rendering support to your XNA content pipeline.
No comments:
Post a Comment