Search code examples
camerarotationqt3d

Qt3D Billboards: how to make plane always face to camera


I try to use camera's viewVector to make plane face to camera, but it will turn Clockwise or Counterclockwise when Camera rotate to left or right.

Can I make the plane always face to camera without turning Clockwise or Counterclockwise?

begin

camera left rotation : plane turn Counterclockwise

camera right rotation : plane turn clockwise

I think camera->upVector() can help me maybe, but I don't how to use.

My code :

class planeTransformClass : public Qt3DCore::QTransform {

public:
    planeTransformClass( Qt3DCore::QNode *entity = nullptr ) :Qt3DCore::QTransform(entity) {}

signals:
    void faceTo( QVector3D v ) {
        setRotation(QQuaternion::rotationTo(QVector3D(0,1,0), -v));
    } ;
};
// Background
        Qt3DCore::QEntity *planeEntity = new Qt3DCore::QEntity(rootEntity);
        Qt3DExtras::QPlaneMesh *planeMesh = new Qt3DExtras::QPlaneMesh(planeEntity);
        planeMesh->setHeight(2);
        planeMesh->setWidth(2);

        Qt3DExtras::QTextureMaterial planeMaterial = new Qt3DExtras::QTextureMaterial(planeEntity);
        Qt3DRender::QTexture2D *planeTexture = new Qt3DRender::QTexture2D(planeMaterial);

        FlippedTextureImage *planeTextureImage = new FlippedTextureImage(planeTexture);
        planeTextureImage->setSize(QSize(3000, 3000));
        planeTexture->addTextureImage(planeTextureImage);
        planeMaterial->setTexture(planeTexture);
        planeMaterial->setAlphaBlendingEnabled(true);

        // Transform
        planeTransformClass planeTransform = new planeTransformClass(planeEntity);
        planeTransform->setRotationX(90);
        planeTransform->setTranslation(QVector3D(2, 0, 0));

        planeEntity->addComponent(planeMesh);
        planeEntity->addComponent(planeMaterial);
        planeEntity->addComponent(planeTransform);

        // connect camera's viewVectorChanged
        camera->connect( camera, &Qt3DRender::QCamera::viewVectorChanged, 
                 planeTransform, &planeTransformClass::faceTo);

Solution

  • Solution using geometry shader

    There is already a C++ translation this QML code that I tried to translate (using geometry shader):

    https://github.com/ismailsunni/qt3d-custom-shader

    My own translation can be found here. It works now after solving the issues mentioned in this question.


    Solution without geometry shader

    I got a different version running based on this bug report. You can find my implementation on GitHub. The billboards don't change their size when the camera moves, i.e. become smaller and larger on screen like every other object, but I hope you can work with that.

    On the master branch the images also move for some reason as can be seen in this image:

    enter image description here

    The no_instanced_rendering branch doesn't use instanced rendering and displays everything correctly.

    Edit I'm sorry I'm not using your example but I don't have time anymore to adjust it. Check out the patch related to the bug report I mentioned. The person implemented a material with this effect, you should be able to extract it and make it run.