mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
101.98k stars 35.33k forks source link

svg import in SVGRenderer #4429

Closed ricserje closed 6 years ago

ricserje commented 10 years ago

hi i´ve seen some closed post about svg support and SVGRenderer and i wonder if maybe in the future it could be possible to import an svg file, manipulate and render in a SVGRenderer in threejs? i know there are other libs to work with svg like fabric and snapsvg that last one has good feats to work with svg files to import and manipulate them but limited to 2d svg transforms

thanks

mrdoob commented 10 years ago

What exactly do you want to do? Have a SVG in 3D? Maybe CSS3DRenderer can do the trick already?

ricserje commented 10 years ago

HI, Thanks for the quick answer

with the CSS3Drenderer i guess u mean something like loading the svg using another lib and load it like a website, like this example of yours

(this demo needs webgl for the iframe sites i guess, right?) http://www.mrdoob.com/lab/javascript/threejs/css3d/

thats an alternative, but i was hoping to use the three js 3d transforms in the svg elements loaded from the file directly, well, thats what i thought that if it could be made, it will be nice =D.

and keep using the SVGRenderer to avoid loosing res.

something like this qrcode demo (https://github.com/mrdoob/three.js/blob/master/examples/misc_ubiquity_test.html)

i guess that if i want to manipulate the svg with threejs i need to separate it by layers ,and wrap those slices of svg in divs and then use the CSS3DRenderer and threejs transforms to manipulate them in 3D

the magic in the other libs i mentioned before is the use of one svg loaded file i guess, cause when the file is loaded each children could be manipulated with svg transforms

i'll try with the CSS3Drenderer to see how it goes UPD: waiting the (preserve-3d-less feat) https://github.com/mrdoob/three.js/wiki/TODO , and SVGLoader to get in the list =D

Thanks

mrdoob commented 10 years ago

I see... I guess we could try doing a SVGLoader...? /ping @zz85

ricserje commented 10 years ago

That would be really nice , it will remind me these feats back then in flash =D

http://www.infiniteturtles.co.uk/blog/away3d-24-34-released http://code.google.com/p/vectorvision/

Looking forward to it

Regards

zz85 commented 10 years ago

Opps, just saw this thread. is @sojiro talking about importing an SVG image into a perhaps webgl three.js scene?

One way is to simply convert the SVG to an image and load it as a texture. You could also try parsing it (if you wish to turn it into a THREE.Shape kind of an object).

Not sure what happens if the SVG contains animation, blurs or stuff though...

ricserje commented 10 years ago

hi, well the idea was to keep the infinite res that the svg has, but if you parse it as canvas then it will blur, i was trying to achieve something like the misc_ubiquity_test.html demo with a svg file loaded into a shape, like we used to do in flash. thats where the SVGLoader idea came trought from Mr Doob, but there are a lot of loaders in the waiting line hehe

https://github.com/mrdoob/three.js/wiki/TODO =)

zz85 commented 10 years ago

I'm not familiar with SVGRenderer, but providing vector support might be the easiest in CanvasRenderer. From my own experimentations, even fonts get rasterized in Css3DRenderer.

Support for vector graphics may be possible in WebGLRenderer, but it requires some knowledge on rendering vectors in shaders. Not so simple I think. See http://http.developer.nvidia.com/GPUGems3/gpugems3_ch25.html and https://github.com/openframeworks/openFrameworks/issues/1190

zz85 commented 10 years ago

Also of interest https://www.shadertoy.com/view/Xds3Dn

zz85 commented 10 years ago

On second thoughts, despite having some progress with #4746, having full support for SVG in WebGL / CanvasRenderer but is probably not something I should do (even though its possible like http://fabricjs.com/test/svg_import/)

Will try to look into the SVGRenderer a little if I have the time..

zz85 commented 10 years ago

Actually SVGLoader's pretty easy to write (6f01c2dc4b9c79a555de5e0cadb25f8bc825c7af)

screenshot 2014-05-02 10 20 54

It also works well with the Css3DRenderer except that rasterization can be seen when zoomed in.

screenshot 2014-05-02 10 21 28

I think loading a svg doc in SVGRenderer might need a bit of work though...

Usage

loader = new THREE.SVGLoader();

loader.load('android.svg', function( element ) {

    var object = new THREE.CSS3DObject( element );

} );
zz85 commented 10 years ago

ok, after looking into SVGRenderer, I'll leave supporting native SVG elements for another day (or another person).

The reason is that SVGRenderer is currently basically a renderer which displays SVG elements to represent the renderable faces generated the scene projected by the projector. To allow a SVG element to be rendered independently from the others means making an exception in the SVGRenderer.

Somehow CSS3DRenderer could be a better fit for rendering SVGElements since the renderer handles DOM elements directly. CSS3DRenderer applies its own matrix transformations directly on the element's CSS.

While SVG objects can also be css-3d transformed, they would be rasterized as mentioned above, so you do not get the infinite scaling. SVG element does support its own matrices, transformation, scaling, and skewing too, but I believe these are all limited to 2D as opposed to 3D.

Again, it might be possible to handle that (treat the SVG element as a plane, project it from 3d to 2d screen space, use the transformation of its original rect -> the new 2d screen space, apply the new transformation to svg), but handling SVG is going to be a special case.

So, perhaps another day, or another person :)

christopherreay commented 8 years ago

hey @zz85 has this question been made obvolete? I know someone who has already developed their own algorightms for 3d transforms for SVG... https://github.com/ndebeiss/svg3d is the project. Nicolas Debessiat.

mrdoob commented 6 years ago

Closing in favour of #13478