1
\$\begingroup\$

I'm trying to compute a matrix to have object always facing the camera. For the moment, my result look pretty good, the problem is that my original billboard scale isn't preserved (Every billboard have a size of 1/1).

Here is what I've done using this post:

glm::vec3 look = glm::normalize(camera->getPosition() - objectPosition);
glm::vec3 right = glm::cross(up, look);
glm::vec3 up2 = glm::cross(look, right);
glm::mat4 transform;
transform[0] = glm::vec4(right, 0);
transform[1] = glm::vec4(up2, 0);
transform[2] = glm::vec4(look, 0);
transform[3] = glm::vec4(objectPosition, 1);

glm::quat q = glm::quat_cast(transform);
objectTransformable->setOrientationFromQuat(q);

I've tried to add something like that but the result is a bigger object with bad proportion:

transform = glm::scale( transform, objectScale );

To resume, I would like to extract orientation from result matrix to apply it on my transform object, something like Unity:

MyTransform.LookAt(Cam.transform.position, upVector);
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

historically billboards matrix just copy the camera view matrix, and replace the last row with their own world position. the scale can be world-fixed if you want trees or hard stuff.
But it can also be screen-fixed for halo effects, in which case you need to scale using the euclidian distance. this can be done in the vertex shader rather than on CPU as an object matrices preparation step. but it doesn't matter much which way is used.

note that using the view matrix partial copy, you will get distortions on the border of the screen caused by perspective projection. another approach to mitigate that is to rotate the billbord so that it faces the view point. This is actually what you are doing right now in the code posted abode. because you use the "eye -> billboard" ray as a base for the matrix.

\$\endgroup\$

You must log in to answer this question.

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