# Screen space quads - 2

Hello All,

This is a continuation of this thread

I didn’t want to mix up the two things.
So, i want to draw screen-space constant quads using a perspective matrix. There were two approaches i had in mind.

1. Mixing ortho + perspective matrices.
2. Using scaling to maintain screen-space constancy.

I am now trying the second approach. The approach is slightly different. What i do is:

1. Obtain the point in camera space where the quad is supposed to be placed(this is the origin of the quad).
2. I use the camera’s up and right vectors to generate a quad, thinking that the quad would be screen aligned.

Now, i don’t get the quad to be screen aligned. I’m not sure what could be the problem. Can anyone please let me know if this concept is right?
i.e
If I use the right vector and the up vector of the camera to generate a quad in camera space, would it always be screen-aligned?
(I was trying this so that i can skip billboarding.)

Thanks!

Do you want to draw the quad with a fixed number of pixels width no matter what the depth it is from the camera or do you just want simple camera facing billboarding?

I want both of these.
So, my idea was, based on the depth, i scale the quad, thus ensuring fixed screen-space size. And since i construct the quad using up and right vectors, i assumed it would be aligned with the screen(i.e billboarded).

Please let me know if this assumption is correct.
Thanks!

Yes, provided that that the forward, up and right vectors are mutually perpendicular. Functions such as gluLookAt() normally use one vector directly then use cross products to generate the other two axes. So even if the vectors aren’t perpendicular, you still get an orthogonal basis.
If you’re using right and up (as opposed to forward and either right or up), the resulting quad should always be parallel to the projection plane, although it might be a parallelogram (rather than a rectangle) if the vectors aren’t perpendicular.
When one of the vectors is a forward vector (as is the case for gluLookAt()), the forward direction (Z) is normally preserved, while the other two are generated using cross products. If the other vector isn’t perpendicular to the forward vector, the resulting quad won’t be parallel to the projection plane.

[QUOTE=GClements;1251627]Yes, provided that that the forward, up and right vectors are mutually perpendicular. Functions such as gluLookAt() normally use one vector directly then use cross products to generate the other two axes. So even if the vectors aren’t perpendicular, you still get an orthogonal basis.
If you’re using right and up (as opposed to forward and either right or up), the resulting quad should always be parallel to the projection plane, although it might be a parallelogram (rather than a rectangle) if the vectors aren’t perpendicular.
When one of the vectors is a forward vector (as is the case for gluLookAt()), the forward direction (Z) is normally preserved, while the other two are generated using cross products. If the other vector isn’t perpendicular to the forward vector, the resulting quad won’t be parallel to the projection plane.[/QUOTE]

Thanks for the reply!
I obtain the up vector and the right vector from the modelview matrix(the first and the second column of the matrix), normalize them and use them.
Aren’t these orthogonal? Can you please clarify that?

with a geometry shader you can computer this stuff on the fly

``````
gl_Position = u_CameraProjection * (vec4(-u_Radius,-u_Radius,0.0,0.0) + u_CameraModelView* gl_in.gl_Position);

``````

This will give you a camera facing vertex with world coordinate offset u_Radius,u_Radius from the center point

``````
gl_Position = vec4(-0.1,-0.1,0,0) + u_CameraProjection * u_CameraModelView* gl_in.gl_Position);

``````

and this is a fixed screen offset from the same point

Thanks for the reply!
I’m using OpenGL 2.0, so no geometry shaders [QUOTE=myk45;1251628]I obtain the up vector and the right vector from the modelview matrix(the first and the second column of the matrix), normalize them and use them.
Aren’t these orthogonal? Can you please clarify that?[/QUOTE]
That depends upon how the modelview matrix has been constructed. The columns of an identity matrix are orthogonal. Rotation, translation and uniform scaling preserve orthogonality. Composition of non-uniform scaling and rotation will result in non-orthogonal axes.

But if you’re using vectors extracted from the modelview matrix, those won’t be screen-aligned. OpenGL doesn’t have a “camera”. Or, rather, the camera remains at the origin facing along the negative Z axis (assuming that you’re using something like gluPerspective() to generate the projection matrix). Camera movement is simulated by applying the inverse transformation to the world, i.e. moving the world around into the camera’s view. So the modelview matrix is the inverse of what would be the camera matrix in a system which used cameras.

So if you want a set of axes which are aligned with the “camera”, you need the columns of the inverse of the modelview matrix. However, for an orthonormal matrix (a matrix constructed solely from rotations), the inverse is just the transpose. So if your modelview matrix has been constructed using only glRotate() and glTranslate(), you want the first two rows of the top-left 3x3 submatrix (i.e. ignoring the right-hand column which contains the translation and the bottom row which should just be [0,0,0,1]).

Thanks a lot for the reply GClements!
That was what i was looking for. So, i have a concept issue here.
I will try the solution you’ve provided.