I'm working on adding billboarded sprites to a game engine, but the engine allows for walking on curved terrain, like spheres. In order to look like the player is walking on the terrain, I want to start with the billboard, then rotate it around its origin (bottom centre) so that its up vector matches the screenspace normal of the terrain.

Here's a diagram of the general idea:

A billboarded sprite is shown on a grid, and how the canvas is angled to present flat to the camera. Then, he same sprites are shown on the surface of a sphere, with how they should rotate to present.

The billboarding works fine - passed the camera's rotation matrix to the sprite, and the poly quad's 0,0,0 is at the bottom centre of the canvas.

How can I get the angle between the normal and screenspace up?

I think it's a matter of projecting the normal with the MVP matrix, to get it as a 2D screenspace vector to calculate the angle from. But I'm not having much luck attempting to implement it.

The sprites take their positioning from the centre of the tiles, along with the normal. I'd also like to move the sprites down in the rotated axis, so that they cover the tile they're standing on.

Any other methods are welcome too.


1 Answer 1

worldNormal = modelMatrix * vertexNormal;

x = Dot(camera.right, worldNormal);
y = Dot(camera.up, worldNormal);

angleaRadians = Atan2(-x, y);
  • \$\begingroup\$ That works perfectly, thank you! \$\endgroup\$
    – bonzairob
    Commented Sep 29, 2019 at 18:09
  • 1
    \$\begingroup\$ You can click the checkmark icon to the left of the answer to mark it as accepted, if it works for you. \$\endgroup\$
    – DMGregory
    Commented Sep 29, 2019 at 18:20
  • 1
    \$\begingroup\$ Can you elaborate on which cases in gives a result different from what's desired, and in what way it differs? We'll need these details to suggest specific fixes. \$\endgroup\$
    – DMGregory
    Commented Oct 6, 2019 at 11:16
  • \$\begingroup\$ After further experiments, it turns out I can simplify it further - no need to even run the modelMatrix projection, just use the normal vector for the dots. (Sorry about the deleted comment, had the idea halfway through writing it!) \$\endgroup\$
    – bonzairob
    Commented Oct 6, 2019 at 11:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .