Canvas vs. SVG for games [closed]
Asked Answered
K

1

36

I realize there are many tutorials and sites and everything answering "Which is better for game applications?" They all say that SVG is not suited towards game applications, that canvas is. But this confuses me.

  • Once something is drawn to the canvas, it is forgotten.
  • SVG elements can be changed after creation, without touching any other visual items in the game.
  • Canvas does not have built in animation
  • SVG has built in animations

So let's say I'm making a platformer. I want the main character to walk across the stage with a beautifully painted background. In Canvas, I either have to recreate her entire hitbox (repainting the spot of every moving entity), or make a separate canvas element and use maybe ctxChar, ctxBG, ctxItems etc. With SVG, on the other hand, it's built in. And I can even just put an <animate> tag inside her <use> tag that changes her x position (or manually change it via js), and another <animate> tag to change her sprite. And then the background never has to be touched.

As for animating a bunch of elements simultaneously, I don't see how that's any faster in Canvas than in SVG. What's wrong with putting svg elements in groups? Can it be any slower than redrawing the hitboxes's backgrounds and redrawing the entities themselves for all entities?


Edit: I think my real question is not if SVG could work, but why people think it couldn't.

Komi answered 11/8, 2016 at 16:43 Comment(9)
You render every frame when animating. No need to have the canvas hold and do animations you do that in Javascript. It animates and keeps track of all contentRivkarivkah
If your game is Background + Player + 15 platforms then both SVG & Canvas would work fine. By the wording of your question you are leaning towards SVG so why not rough-out the game in SVG to see if it suites your coding style?Execrative
Re your Edit: SVG is heavier because all the components are managed (managed==have events, changeable styles & auto-redraw when animating). For your case SVG will work fine. Canvas is good for games with hundreds rapidly changing of game components because the components are managed in JS -- and JS is relatively faster than DOM manipulation.Execrative
Just a heads-up about SVG: in Chrome "SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead."Torrefy
Just for the record, the SMIL deprecation notice was reversed quickly (well, 5 days after @AgataB's message) so SMIL is not deprecated. Also, with Microsoft's tech shift, SMIL support is broader than everJalousie
1) It's really odd for this to have been closed so long after it being asked and getting mostly positive feedback. I notice a recent discussion below that echoes the same confusion I had. But this went 4 years before that happened. It's pretty clear it wasn't the question that changed.Komi
2) This isn't too much more opinion based than "How do I get X to run in less time?" because that gets just as diverse and argumentative answers. My problem was that all the previous information I could find was saying "SVG is terrible" but no one was stating why it was terrible, and I needed to know. The recent discussion is not so much differing opinions as it is a lack of understanding on the part of one person.Komi
I would say, give it a try. If it's fast enough for your use-case, then it works. That said, you'll want to do some serious experimentation up-front: create a test-case that has the rough level of scene complexity you anticipate, and make sure it runs fast-enough and looks good. Make sure to use requestAnimationFrame and not setTimeout if you need to setup a game loop. I've used SVG on a simple in-browser fighting game, and it was plenty performant and looked nice. I'm considering it for a platformer, but haven't done any tests yet.Countercheck
The reason I chose SVG was because it worked well enough, and it enabled me to achieve my goal quickly. Basically it's a higher-level platform than using Canvas, where you have to do everything yourself. It's easy and at least in 2021 reasonably performant if you do it right. That said, not sure yet where the performance wall is. Oh and it dovetails really nicely with React, which makes it even easier.Countercheck
R
48

SVG V Canvas

As a professional games creator my advice is to stay away from SVG if you wish to create browser based games. The main reason is that it is simply too slow. Second reason is that it will make your job as a programmer more difficult because finding solutions to SVG's lack of performance is hard. Third reason, because it is VERY SLOW and games are all about performance.

This page will go over SVG game design An Original Approach to Web Game Development Using SVG but before you dive in and read all of it have a look at the prototype of the game it`s all about Runes and Relics Prototype. A little oh hum in my book.

I am sure there are other attempts this was just first up in my search. But I have never played a good SVG game.

So what is SVG good for? Graphic resources. SVG is a good way to package images for your game, Once you have them on the client you can render them to bitmaps and then use them to render your game. The beauty is you get the resolution independent scalability of SVG and small images size. But by rendering them to bitmap at load time you get the full use of the GPU to move pixels about. SVG is just too slow to use within the game.

Why use Canvas? I would like to say because it's fast, but it is not when you compare it to a native C++ app which will run 10* quicker than the equivalent Javascript / canvas game. Ten times quicker is very significant but then you do not get the cross platform advantage you get with Javascript.

Currently canvas is the best option for truly cross platform game applications. Using either 2D or 3D webGL you can build full screen full frame rate games. HTML5 has a good set of APIs for all gaming needs and is easy to learn.

I am not a fan of game engines, they are a cover all solution, the middle man between you and the already well designed API's that force you to do it their (not that great) way. But they will give you a good overview of what is possible.

Phaser is a javascript canvas game engine that has lots of resources and examples. It is a good place to start and see what can be done. Don't be sucked in by the fact that game engines sell themselves as such. HTML5 & JavaScript is out of the box the best game engine in town, runs native code, has a huge user and support base. The time you spend learning how to use a Game engine's API will not be time spent learning how to use the HTML5 API's (and quite frankly the HTML5 APIs are perfect, the result of the 20 year browser wars) which is actually easier than the Game engines to use and learn.

Rivkarivkah answered 15/8, 2016 at 13:39 Comment(22)
Although it doesn't completely tell me why SVG is slow, I suppose this is as good as I'm going to get at my level of understanding. And you did post a resource, hinted at why, and gave me ideas as to how to use SVG and Canvas together, which is probably more useful to me than the information I started out looking for.Komi
@Komi SVG is very difficult to apply Hardware acceleration to. Much of its rendering back end is a mixture of Software and Hardware and thus much slower than pure Hardware rendering back ends. With webGL you can get high performance vector rendering ( with some limitations) but the webGL API is a complex API to pick up and learn. 2D canvas does vectors like SVG but you can also utilise bitmaps and get great Hardware aided rendering, and you get to control how each rendered item is drawn, unlike SVG ( the main reason its so so slow).Rivkarivkah
I don't understand @Rivkarivkah 's hate on game engines. They are extremely useful, and prevent you from re-implementing a buggy version of free & available software. If you're AAA then maybe you need to make one to your own specs, but if you're an indie definitely go with an engine. Do you want to make completed games or only 1/2 finished projects? Compromise: contribute to open source engines (like Phaser), to help them meet your needs.Pretorius
There has been work to leverage the GPU for SVG rendering natively in browsers. Some browsers already support it to varying degrees. GPU manufacturers may one day offer APIs explicitly for this purpose (NVidia has been making a lot of strides in this area). However, if you want to make a SVG game with today's tech, you're going to have to use very simple graphics and know how to optimize them for performance. It is fun though and worth the effort if you're up to the task.Seda
@DimuDesigns Not only SVG rendering it is the XML. You might have hundreds of particle emitters of many different kinds that have spasmodic rendering counts from, with very few individual particles even having any ongoing state. Eg sparks trailing a bullet compAlpha("lighten",0.5);doFor(5,i=>ctx.drawImage(spark,bullet.x - bullet.dx * randCurve(spark.trail.length),bullet.y - bullet.dy * randCurve(spark.trail.width))); The only way I know how to do this in SVG is to have ALL ( max number I expect) the sparks as nodes in the SVG, the overhead is unworkable and impractical.Rivkarivkah
@Rivkarivkah Instead of using multiple nodes per spark I'd use a single path element and update the geometry in the 'd' attribute. Its possible to pack multiple shapes into a single node that way.Seda
@Rivkarivkah Check out the particle effect using animejs. codepen.io/juliangarnier/pen/gmOwJX. They basically have a collection of circle exploding from a pointon the screen; there is a single path node for collections of circles of a specific color. Its pretty nifty.Seda
@DimuDesigns ??Looks nice but all the rendering is done via the 2D API, and each particle needs to keep its own state, plus a complete library that as far as I can tell does nothing but provide a tween (easeOut is pos= Math.pow(time,2)). All you should need is the explosion center, duration, seed, and start time. Each sub part (circle) should be stateless and calculated as needed. If the explosion was off screen, keeping each circle state just incase it moves onscreen is memory and cpu wasteful. if the frame rate drops removing some particles will cost.Rivkarivkah
The runes and relics website link is broken. What kind of game was it? Is there a screenshot available?Sartin
To add to @TheAddonDepot's tip on using a single <path> and update the geometry (d attribute) - you can also link to a <marker> from paths, polylines etc., giving very compact symbol repetition. The line may not even be needed, eg. if you draw stars, snow etc. but the symbols show up. Symbols can even be nested. One of the many options.Jalousie
I found this blog post which links to a performance comparison between canvas and SVG with 1000 particles. The SVG version is 60 fps while the canvas is 160 fps on my machine. medium.com/@jgoz/game-on-on-your-browser-1e7e903dac16Weisbart
I get the feeling this answer is presuming a lot about the game mechanics. For instance, if I needed to draw a very large resource, wouldn't a limit exist at which point SVG rendering is not only enabling smaller file sizes, but also faster performance than bitmap rendering? Doesn't a limit exist at which point tracking complex graphical behavior is less code with SVG? I can understand the overhead of SVG is especially a bottleneck with large number of objects on the screen. See this answer for interesting contrast to some of the points made here.Venose
@Venose Display hardware shows pixels, vectors must be rasterized before they can be displayed. SVG images may also require multiple rasterization compositing steps thus need much more RAM than the same sized bitmap image. By all means use SVG to load resolution independent resources, however there is never a point when SVG is faster than bitmaps due to the additional (slow and memory hungry) steps of rasterization and compositing needed to be able to display the resource.Rivkarivkah
@Rivkarivkah I hear that, but there's data suggesting otherwise and I'd be interested to hear your thoughts on the claim in that link: When varying the size of the drawing area, canvas performance degrades significantly, while SVG performance is completely unaffected. Canvas rendering performance seems to degrade linearly in the number of pixels in the canvas area.Venose
@Venose The statement is wrong. SVG uses the same hardware as the canvas. Double the size of an SVG and there is 4 times as many pixels, same for canvas. As SVG needs to rasterize before it can be composited, bitmaps only need compositing. Try it yourself. BTW the link is over 11 years old and there have been vast improvements to the 2D and WebGL API since then. Nothing beats WebGL / canvas in terms of pure speed and SVG a poor 3rd after 2D /CanvasRivkarivkah
@Rivkarivkah You make sense but (and please don't shoot the messenger) there are more blogs written more recently with interactive demos allowing you to benchmark SVG vs Canvas for different rendering "complexity" that have concluded SVG can be nearly twice as fast (28 FPS vs 15) on modern hardware when rendering "complex" shapes (they certainly agree with you otherwise that Canvas is faster but only when rendering lots of "simple" shapes)... So could there be some truth to this?Venose
@Venose without seeing the code I have zero faith in the results of such test. There is a reason Phaser, Unity, Pixi, and many more JS game engines DO NOT use SVG.Rivkarivkah
@Venose This answer https://mcmap.net/q/209401/-html5-canvas-rotate-image draw 500 (AKA sprites) independently rotated, scaled, copies of an image at 60fps on 99% of devices using just the 2D API, using WebGL this can be pushed to 4000 sprites. SVG simply can not do the same.Rivkarivkah
I disagree with this statement "...and games are all about performance". Aren't they're all about fun? Poor performance can get in the way of that of course...Countercheck
@Countercheck Totally agree games must be fun, but as a commercial developer poor performance means sacrificing quality, reduced visuals, sound FXs, etc... In a saturated and highly competitive market place its the little extra touches that make a game stand out from the crowd, that or a highly original concept.Rivkarivkah
@Rivkarivkah Very fair points.Countercheck
I guess it also depends on what we mean by "game". If game means a commercial game, then yeah it seems like a bad idea to make choices that are going to hamstring performance. If game means a hobby/free game just for fun/professional growth, then I think there's more latitude in choices.Countercheck

© 2022 - 2024 — McMap. All rights reserved.