4

Can someone help me understand how three.js initially determines the size/scale of a sprite?

At the moment I'm working with 4 sprites (PNGs with transparency that are 3000px × 1830px) stacked in 3D space, but I'm having to scale them up between 16x and 22x. In order to keep the sprites from looking squashed, though, I have to scale the y-axis 75% of the x-scale.

Eventually, I want to be able to pull in images systematically, and have them scale appropriately.

It's possible I just haven't set this thing up correctly. It looks right, but it's super hacky-feeling right now. I pretty much changed a bunch of numbers, until it looked right to me. I don't like that. I want to understand.

Here's what I'm working with currently: http://valorink.com/3d-test/stackoverflow/

ironoxidey
  • 143
  • 1
  • 8

1 Answers1

6

Looking into the code of the Sprite class reveals that a simple plane with width and height of 1 is created in the constructor. I wouldn't have expected anything else, because the geometry size is usually not defined by the texture size.

You probably want them to fill the viewport, so you have to scale them. With perspective camera its a bit of math, because the amount of x-scale (or y-scale) to fit the viewport size relates to the distance to the camera. So, it should be something like

var halfHeigt = distanceToCamera / Math.tan( camera.fov/2 * Math.PI / 180 );
y-scale = halfHeight * 2;

And of course you need to consider the aspect ratio in order to not looking squashed. So, x-scale should be y-scale * textureWidth / textureHeight, or the other way round y-scale = x-scale * textureHeight / textureWidth.

Brakebein
  • 2,197
  • 1
  • 16
  • 21
  • This mostly helped me. I marked it as the answer, because my question was about wanting to understand how the Sprite dimensions were determined. And your answer has set me off in a pretty good direction. I don't really understand the formula you gave me for determining `halfHeight`, though. Mostly, I do not understand `Math.tan`, and when to use it. Also, **is there a good way to get the `textureWidth` and `textureHeight`?** I can load the image into a div, get the width and height from it after it's loaded, and then remove it and run the Three.js stuff, but that seems hacky. – ironoxidey Feb 10 '16 at 17:28
  • 2
    `texture.image.width` and `texture.image.height` should give you the the resolution of your texture. The formula determines the scale your sprite should have to fit the viewport. It's a bit of triangulation math. My formula is a modification of [How to fit camera to object](http://stackoverflow.com/questions/14614252/how-to-fit-camera-to-object). – Brakebein Feb 16 '16 at 10:22
  • I'm confused too. Seems like sprite initial size based on parent object and viewport.... I'm thinking of putting in scene instead of mesh. And just moving it around with the mesh? – LrakWortep Jul 12 '17 at 23:38
  • Be aware that any transformation of the parent is also applied to the children. So, if the sprite is a child of the mesh and you scale the mesh, the sprite is also scaled. You could group the mesh and sprite, so the mesh doesn't effect the sprite, but you can move the group to move them both around at once (I'm not sure, if it's that want you want). – Brakebein Jul 13 '17 at 16:08