Sign in to follow this  

True object billboarding problem

This topic is 987 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

 

I'm in trouble trying to do object billboarding to display bones hierarchy.

Question 1 : should I do the billboarding first and then TRS to match the bone position rotation and size or, should I do the TRS first, which I've done already and then rotate around bone axis to align the bone mesh in front of the camera ?

 

Question 2 : I'm trying to do billboarding with a mesh, here are my steps:

1- get the vector object to cam in world space

2- project it on XZ plan by setting its y component to 0

3- normalize it (objToCamProj)

4- get alpah the dot between forward(0, 0, 1) and objToCamProj

5- get the up vector from cross(forward, objToCamProj)

6- create a rotation axis out of up and rotate each vertex by acos(alpha)

7- transform vertexPos by the model, view and proj mat

 

Ok now I think the method should be correct BUT, when rotating the camera around my object, it's fine as long as I'm within the positive Z. As soon as the cam pos is going into negative Z, the rotation angle seams like inverse or something.

 

What am I missing ? (I know for now it's only cylindrical billboard and regarding question 1 I'm doing billboard then TRS)

 

Any help would be much appreciated.

 

Share this post


Link to post
Share on other sites

I think I solved question 2, that is just because you need to disable the culling...

I'll carry on with the spherical billboarding now.

 

What about question 1 ? What would you guys recommend ?

Share this post


Link to post
Share on other sites

Mmmh just to make things right, for an object, in question2 point 1 you need to do this instead:

Transform the camera position into model space by the inverse of the model space then in the shader find the vector vertex to cameraPositionModelSpace

Then you can follow step 2 etc...

Share this post


Link to post
Share on other sites

billboarding to display bones hierarchy ... when rotating the camera around my object

 

That's a bit confusing as "billboarding" is commonly understood to mean changing the orientation of an object to always "face" the camera. However, you mention moving the camera itself.

 

 

 


What am I missing ?

 

You're missing a clear description of what you're trying to do, rather than how you're doing it. wink.png  I.e., do you want to orient the mesh to face the camera, or do you want to move the camera to view the mesh from a different camera position and direction? Or both?

 

EDIT: Unless what you want to do somehow effects the bone orientations in model space, rotating the model in world space is done after the model is configured in model space. I.e., you would do your "normal" vertex transformations in model space, and then apply a world-view-projection transformation.

Edited by Buckeye

Share this post


Link to post
Share on other sites

Ok, back to this problem and my appologies to Buckeye because it took me so long to come back on this subject.

You're right, I don't know how to do what I need to do...

Here with some screenshots, it may help.

 

So basically I need to render a mesh(sort of quad) between 2 joints. So far as you can see I'm rendering the quad as a billboard between those 2 joints, fine.

 

Now, what I really need to do next is to make the starting position of my quad where the red cross is on the second screenshot to the red circle.

 

What this means is that the red cross point is in projection space, its position depends on how far we are from the point.

The same for the distance between the 2 points.

 

At the moment I am able to find the red cross/circle position in projection space by knowing the radius of the joints and using the projection matrix.

But whatever I tried after that didn't work, I tried to unproject those screen coordinate points or distances into world space to use it in my shader but with no success.

 

So my question is not very clear maybe but how would you render a quad between those two joints knowing that its position, orientation and scale need to be computed in projection space ?

Share this post


Link to post
Share on other sites

my question is not very clear ... I need to render a mesh(sort of quad) between 2 joints ...

 

No, it isn't. Once again, you're describing HOW you want to do it, rather than WHAT you want the results to be. You get full credit for trying different things to achieve the results you want. smile.png  However, at this point you haven't described what you want the appearance of something (mesh, quad, ...?) to be.

 

It appears part of the confusion is whether you want to render a mesh or a quad. It's not clear what "sort of quad" means in that context. A quad is 4 vertices. A mesh is either comprised of 4 vertices, or it's not. Further, just so we're working with the same assumptions, the term "quad" does not imply billboarding, 2D rendering, orientation, etc. It's just 4 positions in some space (which space that may be is not defined by the term).

 

Because you mention scale, this is just a guess - do you want to draw a mesh representing a bone that appears the same size on the screen, regardless of it's distance from the viewpoint? I.e., do you want the circles representing the joint positions to always appear to be the same size in pixels (i.e., screen-size rather than world-size)?

 

 

 


how would you render a quad between those two joints knowing that its position, orientation and scale need to be computed in projection space ?

 

Because it's still not clear WHAT you want the results to be, my answer: I wouldn't. biggrin.png Seriously, if the user has chosen perspective projection (rather than orthographic), I would render a bone mesh in perspective - the farther it is from the eye, the smaller it appears. If, in contrast, the joint circles are all rendered with the same radius in screen space, when the user zooms out, it might become a confusing mess of overlapping circles. Your second pix above would be what I would do, because the circle sizes provide visual cues to the user with regard to which joint is closer, and what the relative orientation of the bone is.

 

Still guessing what you're trying to achieve, You may want to consider an orthographic projection. In that case, all objects, near and far, are rendered to the same scale. All the joint circles would be the same size, etc.

 

EDIT: It's important for you to decide what you want the results to be - and to know what the advantages and disadvantages of that are.

 

For my own purposes, because my old eyes need a decent size target for picking, I use an adjustable screen-size bill-boarded quad for points (vertices) in a mesh editor. In the pix below, the screen-size of the quads is identical (~8-12 pixels I think). However, note that, when zoomed out, the fixed screen size of those points gets messy. Note, even with an orthographic projection, using a fixed-size quad for the vertices in the model on the right below, would still result in those quads overlapping when zoomed out.

 

[attachment=27071:fixedsize_closeup.png][attachment=27072:fixedsize_zoomedout.png]

Edited by Buckeye

Share this post


Link to post
Share on other sites

Hi, thx for your comments, here is a picture of how it should look like, well sort of.

I definitly want the joints and bones to have a different scale so I don't want to use ortho matrix.

The joints and bones are meshes, they have a geometry, they are not quad sorry. I called them quad just because they don't have any thickness and I render them as billboard but they are not quad.

 

The problem is to render the bone mesh between the joints so the bone mesh never touch the joints but is like attach to its border. And with the 3d perspective this is impossible to acheive if you look at my previous picture with the red cross you'll see that with those kind of angle in 3d the bone mesh will come from behind the joint of course.

 

I hope this is clarifying a bit the problem, but in this picture, we don't quite see the problem as there is no bones really that is along the z axis more or less.

 

I know this is very confusing and it's hard to explain the problem because it happens only if you look at it from an angle.

Share this post


Link to post
Share on other sites

the bone mesh never touch the joints but is like attach to its border

 

 

I think I'm starting to get the idea. If I understand your description and the image, the joint appears as a billboarded circle; the bone mesh is just the trapezoid shape.

 

You can calculate the world position of "attachment" point for each end of the bone mesh. This assumes that the radius of the joint circle is constant is world units.

 

[attachment=27075:joint_calc.png]


 

The idea is to determine the direction of the green line, and use that to position one end of the mesh. I.e., given 3D positions of the 2 joints j1 and j2:

 

Vector3 dir = normalize( j2 - j1 );
Vector3 meshPosition1 = j1 + radius * dir;
Vector3 meshPosition2 = j2 - radius * dir;


With regard to billboarding the mesh, I would strongly recommend that you construct a 3D mesh shape, perhaps something like the bones in Blender (see below), render it and consider that the shape provides a visual cue to the orientation of the bone. That's not just laziness; if you rotate the view, or rotate the model, those visual cues of rotation will make it much easier for the user to understand what's being seen.
 

 

[attachment=27076:bonemesh.png]



EDIT: If you want to render the mesh in screen-space, calculate the two mesh positions as shown, and project them into screen-space.

Edited by Buckeye

Share this post


Link to post
Share on other sites

You helped me to clarify the problem. It's not done yet but I need to do more tests.

So now I have the point E which is along j1 to j2 at the edge of j1 radius. E is express in screen-space, I transform it in the range -1..1 and in the shader I don't do neither the view nor the projection transform.

So now my mesh is always positioned correctly as I want it to just doing :

gl_Position = modelToWorld * vertexPos;

in the vertex shader.

 

 

That is a good step for me. Now I just need to scale it and orient it using the same method I guess. Scale shouldn't be a problem. I'm more afraid of the orientation.

I'll have to do some more tests. Thanks for the help, I'll let you know.

Share this post


Link to post
Share on other sites

Ok, I'm sorry but this is driving me crazy. I thought I had the proper E point coordinates in screen space but this is not the case.

 

Basically I have those 2 joints and in world space they have the same radius. But with the perspective projection and depending on the angle I'm looking at it, their proportions are changing of course.

 

But it seems I'm not able to find the radius properly, in screen space coordinates that is.

 

So could someone explain me how I could compute the length of the projected radius ?

 

I tried using the camera to J1 distance over focal length, then multiply that by my radius but it doesn't match.

 

I also tried to get the unit vector from J1 to J2, multiply it by the radius, project it in screen space, but even that is not giving me the flat radius.

 

First picture shows how it should look but from any angle point of view.

As you can see in my second picture, my bone is not starting from E but a bit before and that is using the projected radius method.

 

So what would be the simplest math method to compute the distance from J1 centre to E ? (and again, this cannot be done in world space)

 

Tanks a lot

Edited by Rannion

Share this post


Link to post
Share on other sites

Ok, for those who were following this ticket, this is dead simple. I guess I needed a good night...

 

To find the point E, I was projecting in screen space j2-j1 * radius. This is of course projecting the real 3d position.

What we need to do here is to find the projected radius length which is on the plane of the camera so: j1 + camUp * radius;

Project that result and then just do (projJ1Pos - projRadius).len() = projRadiusLength;

 

Then from here of course you can find E = projJ1Pos + (projJ2Pos - projJ1Pos).normalize() * projRadiusLength.

 

As mention in previous post, this is in screen space so we divide x and y by screen width and height, put everything in the range -1..1 and we are done.

In the shader no need for view nor pojection transform, just modelToWorld transform.

 

Share this post


Link to post
Share on other sites

This topic is 987 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this