I'm trying to implement vertex shader code to achieve the "billboard" behaviour on a given vertex mesh. What I want is to define the mesh normally (like a 3D object) and then have it always facing the camera. I also need it to always have the same size (screen-wise). This two "effects" should happen:
The only difference in my case is that instead of a 2-D bar, I want to have a 3D-object.
To do so, I'm trying to follow the alternative 3 in this tutorial (the same where the images are taken from), but I can't figure out many of the assumptions they made (probably due to my lack of experience in graphics and OpenGL).
My shader applies the common transformation stack to vertices, i.e.:
gl_Position = project * view * model * position;
Where position
is the input attribute with the vertex location in world-space. I want to be able to apply model-transformations (such as translation, scale and rotation) to modify the orientation of the object with respect to the camera. I understand the concepts explained in the tutorial but I can't seem to understand ho to apply them in my case.
What I've tried is the following (extracted from this answer, and similar to the tutorial):
uniform vec4 billbrd_pos;
...
gl_Position = project * (view * model * billbrd_pos + vec4(position.xy, 0, 0));
But what I get is a shape the size of which is bigger when is closer to the camera, and smaller otherwise. Did I forgot something?
Is is possible to do this in the vertex shader?
uniform vec4 billbrd_pos;
...
vec4 view_pos = view * model * billbrd_pos;
float dist = -view_pos.z;
gl_Position = project * (view_pos + vec4(position.xy*dist,0,0));
That way the fragment depths are still correct (at billbrd_pos
depth) and you don't have to keep track of the screen's aspect ratio (as the linked tutorial does). It's dependent on the projection matrix though.