SVG-based texture scaling

I need to visualize extremely large svg (content is more than 300000 rows).

The only way to zoom and pan it rapidly and smoothly without overloading the DOM is using canvas with webgl context. I have tried 2d context, but interaction is still pretty slow.

I have loaded my svg to threejs texture and the only problem I am facing with is picture quality when I zoom in.

I understand, that canvas is based on pixels and it is not scalable graphics. Anyway, is there a way to make it crisp when I zoom in to any scale level?

I have heared about mipmaps, could they help me by any chance? Or maybe there are another methods how to solve this problem, maybe another libs…

I would really appreciate any help, as I’ve already spent a lot of time without any proper results.

Can you try to load the SVG with SVGLoader instead? See webgl_loader_svg for more information.

In this way, you are not using SVG as a texture but the shapes are triangulated and rendered as a group of meshes.

Can you show how it looks? If it’s simple you could do some pseudo virtual texturing by instead resizing the texture which would be expensive and limited scaling the svg rendered to canvas, by this in theory, your canvas size max. would be the size of the viewport but has no zooming limits.

You would have to find the smallest face aligned quad of the frustum. But it’s really not simple. A simple approach but limited in tessellation would be what Mugen suggested to convert it to a geometry. It depends on how deep the zoom has to be and if edgy lines (if they appear for the mesh) are ok for you.

Yeah, I tried threejs SVGLoader. It’s unable to manage with my svg. I get some weird shapes instead.
I also tried fabricjs svg loader, it works well, but they don’t have WebGL support.
So, that’s why I’m trying to do it using textures.

Have your tried any kind of optimization on the SVG? A popular library is https://github.com/svg/svgo

There are a lot of parameters for path simplification and merging that could potentially allow your svg to behave normally with the general loader.

It’s probably better to work with the file than work around the code.

Yes, the file is optimized already.
We are talking about very large dataset, described in svg.

It would be good to see how it looks and how you display it.

1 Like

Hmm, could you share the SVG file, maybe we can figure something out.

Here it is
https://gofile.io/d/U118ow

A bit simplified version, but still large.

That was indeed interesting to see, have you considered just converting that dataset into something easier to display? You could for example only use the positions and numbers and display them with point sprites, making the circle simply in fragment shader so it looks just as vector. There would be no texture involved anymore and it’s blazing fast.

It does kind a look like exported from a program? Anyway converting to geometry with SVG loader can’t really be an option here with the circles already. If you can get the data in a different format like an CSV table you can avoid the SVG.

I get this SVG as it is, furthermore, it can include other kinds of shapes, pattern fills, etc.
I don’t have to care about its contents, that’s why I need an approach to load it as scalable texture.
Can mimpmaps be a solution in my case?

@Dudeskin15 does it have to be in three.js? Do you simply need pan / zoom support? If so I could offer some workable solutions.

No, they are used to perform „downscaling“ as textures getting subpixel in distance would result in a pixelated soup on screen without them.

Depending on what your needs are, you could also give the CSS3D renderer a try, since you will be able to render the actual scalable svg in an element.

Furthermore you could even mix CSS3D with a WebGL canvas.

Not necessarily three.js, it could be any solution that will make it work.

How will CSS3D renderer help me? I mean, wouldn’t svg be loaded as a texture in this case too?
Do you have any examples of how to implement it?

my experience with SVG has been mixed. I had a similar problem to solve several years back. I used SVG for representing diagrams of electronic circuits, and I quickly realized that SVG rendering is slow. I have implemented a bunch of optimizations on that project, most important of them was usage of a spatial index, second was building bitmap tiles out of the image with different mip levels. It’s not a straight-forward