[SOLVED] Billboard issue

Here’s the example project. I am using the billboard script with augmented reality. I’d like to pokemon to stay vertical even when I turn the phone. I’ve been playing with the billboard script to achieve this unsuccessfully. I am attaching a video demonstrating the problem

Lol the video doesn’t actually show the problem. Try it yourselves. Tap to place. Then start to rotate the phone. The pokemon will turn and not stay straight facing you.

Hi @Marks,

If I understand correctly, you would like to rotate that entity to always face the camera?

Then you should be using lookAt, something like this:

    var cameraPosition = this.camera.getPosition();

    // Always face the camera
    this.entity.lookAt(cameraPosition, this.camera.up);

If I understand correctly, you would like to rotate that entity to always face the camera?

The pokemon should always face me vertically. If you launch on your phone in portrait position and place the pokemon and walk around it. You will see that the pokemon always faces you, that’s correct. However, if you start rotating your phone to landscape mode, the pokemon will stop being vertical in relation to you, it will start to go horizontal. The video couldn’t show that because it doesn’t record the phone rotation.

I tried your code and it doesn’t work, in addition to making the pokemon face the other way :joy:

Is this without auto rotate on the phone? ie this is what you are seeing?

Not exactly. Only the pokemon looks like that(which is the issue), but the rest of the scenario looks right even when turning the phone(the real world camera feed is rotation-independent). The billboard works as I want as long as the user use the phone in portrait mode only. Once it completely switches to landscape the pokemon looks correct again, but unfortunately it must look correct when the user is in the process of turning the phone as well. Not sure if this is a billboard adjustment or something else.

Can you take a screenshot of your phone screen when it is in landscape and you see your issue please?

It’s almost the same thing but the scenario looks correct. It’s in the process of turning to full landscape, it didn’t switch to landscape mode yet. It’s in this process that the pokemon should look vertical as well. Once it fully switches to landscape it looks correct again. The billboard should compensate for this phone rotation or something.

As your phone has rotated the screen to be in landscape but not actually rotate the screen, as far as the code is concerned, this is correct because there’s nothing in the code that is taking into account of phone orientation.

What I would do is to use the AR tracked ‘world’ up vector to use as the up vector for the look at function so that it’s always orientated according to the AR tracked ‘world’ and not pc.Vec3.UP which is the PlayCanvas World up.

And this would mean just a small correction on the Dratini model rotation on the Y axis so it’s facing the right way using lookAt

https://playcanvas.com/project/991526/overview/f-billboard-problem

2 Likes

Thanks, this works. Is there a way to do it without having to rotate the child node 180 on the y axis? I guess I can just apply the rotation on the script to not affect the editor, but it’d be better if I didn’t need to touch the rotation of the model at all.

I just added the following line and it works, but I hope there is an alternative without having to do this

this.entity.children.forEach(child => child.setLocalEulerAngles(child.getEulerAngles().x, 180, child.getEulerAngles().y));

Re-export the model so that it’s facing down -Z (PlayCanvas/Right handed coordinate system forward) or build the entity transform matrix yourself.

Ok, nevermind then. It needs to look correct in the editor as well. Eh, not a big deal, just rotate at runtime. Just a small improvement to the script, you don’t need to create the world axis entity

//apply to a parent group, not the entity you want to rotate itself.
var ArBillboard = pc.createScript('arBillboard');

// initialize code called once per entity
ArBillboard.prototype.initialize = function() {
    this.camera = this.app.root.findByName('Camera');
    this.worldAxis = this.app.root.findByName('Instant Tracker');
    this.entity.children.forEach(child => child.setLocalEulerAngles(child.getEulerAngles().x, 180, child.getEulerAngles().y));
};

// update code called every frame
ArBillboard.prototype.postUpdate = function(dt) {
    this.entity.lookAt(this.camera.getPosition(), this.worldAxis.up);
};

I’ll just leave the final script here. You can close this thread if you want. Thanks for the support.

1 Like

Back at this again…now I need to make the pokemon rotate while lied down, and turn on the z axis after placed. Like when you are on the bed and turn your head

I tried different combinations of the lookAt with right, left, up, etc…none of them seem to work. I created a new sample project

https://playcanvas.com/project/992162/overview/billboard-problem-again

Like this? https://playcanvas.com/project/992256/overview/f-billboard-problem-side

All I did was rotate the model entity by 90 degrees on the Z axis

Hm…no. I made a video, hope it helps. The model needs to rotate only on the x axis. The white plane is the floor. If I go behind the model, it should stay upside down. On the video I move the camera to different angles and rotate the model to simulate different point of views.

Sorry, I don’t really understand what you are looking for here but it sounds like it’s bespoke behaviour on how it looks at the camera. Unfortunately, I can’t spend more time on this to work out exactly what you need here.

It sounds like you want the model to only rotate on it’s local Y axis and ‘roll’ to face camera without full on billboarding.

It sounds like you want the model to only rotate on it’s local Y axis and ‘roll’ to face camera without full on billboarding.

Yes. Although on the video I’m rotating on the x axis.

As mentioned in the last post, I can’t spend more time on this. Basically, you would need to project a point in space from the camera position, in the direction of the model’s local Y axis that intersects with the model’s XZ plane.

Once you have this point, you can call lookAt at it