Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the three.js SVGLoader render svgs upside down?

I've been using the group.scale.y = -1; trick on groups to render my svgs in three.js the right way up.

However this messes with the concept of the y coordinate displaying positive values up from the center of my group. Usually the positive y coordinates on the paths would push the svg drawing up (much like the positive x coordinate still pushes to the right) but the scale flip trick to correct the upside down svg also flips the direction by which the y coordinate places the svg. Hence a greater positive y value places the svg further towards the bottom of the canvas.

Can anyone explain why the svgs are rendered upside to begin with and perhaps explain how to fix this so my y coordinates still behave as expected?

like image 334
lorless Avatar asked Oct 29 '25 13:10

lorless


2 Answers

For anyone interested in this the reason that SVGs are rendered upside down in Three.js is due to the point from which they are rendered.

In SVGs it appears that while the X axis has positive values it draws further to the right and while the Y axis has positive values it draws further down. This is calculated from the top left point of the image.

In Three.js you have the ability to move left of center (X:0, Y:0) and below center. This is achieved via negative values. In Three.js the canvas asserts that positive Y values move up and negative Y values move down.

As the Renderer draws paths/shapes it uses the original Y value from the SVG which will usually be a positive number causing the drawing coordinate to move up instead of down (like it would usually do in an SVG) which has the effect of drawing your SVG upside down.

like image 172
lorless Avatar answered Nov 01 '25 04:11

lorless


In the SVG loader example: https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_svg.html

You could also flip the actual geometry, not the group scale. This way the object and or group maintain consistent scale information.

for ( var j = 0; j < shapes.length; j ++ ) {
    var shape = shapes[ j ];
    var geometry = new THREE.ShapeBufferGeometry( shape );
    geometry.applyMatrix4(new THREE.Matrix4().makeScale ( 1, -1, 1 )) // <-- this
    var mesh = new THREE.Mesh( geometry, material );
    group.add( mesh );
}
like image 45
Seth Walker Avatar answered Nov 01 '25 03:11

Seth Walker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!