• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
metsfan

Screen-aligned Billboarding, Need help.

2 posts in this topic

THIS HAS BEEN SOLVED.  Feel free to let this thread die, but I welcome any feedback.

 

Hello all,

 

I am trying to do screen-aligned billboarding of some text labels, and I am having some trouble.  The following is my code for calculating the billboard matrix:

// Up vector from view matrix
CEVector3 up = CEVector3Normalize(CEVector3Make(viewMatrix.m10, viewMatrix.m11, viewMatrix.m12));
// Normal vector from near plane
CEVector3 normal = [camera.viewFrustum planeAtIndex:NEAR].normal;
// Negate the normal vector
normal = CEVector3MultiplyScalar(normal, -1);
    
// Verify that up and normal are perpendicular.  If not, something is wrong.
double dot = CEVector3DotProduct(up, normal);
if (dot < 0.00001) {
        // Calculate the right vector
        CEVector3 right = CEVector3Normalize(CEVector3CrossProduct(up, normal));
        // Create billboard rotation matrix
        billboardMatrix = CEMatrix4Make(right.x, up.x, normal.x, 0,
                                        right.y, up.y, normal.y, 0,
                                        right.z, up.z, normal.z, 0,
                                        0, 0, 0, 1);
}

 

 

Then, to apply this matrix to a feature, I do the following.  

 

// All features are at position 0 on the z axis.
CEMatrix4 modelViewMatrix = CEMatrix4Translate(billboardMatrix, feature.position.x - cameraPosition.x, feature.position.y - cameraPosition.y, -cameraPosition.z);

 

I have tried also using the column vector of the view matrix instead of the row vector and transposing the billboard matrix, and all combinations, and nothing seems to produce the correct results.  

 

My view matrix does have some weird transformations like scaling and shearing, not typical of examples of I've seen with billboarding.  In fact, when I disable the scales and shears, the billboarding seems to work fine, but when I enable them again, it acts very very strange.  The labels do show up, but they come in from all directions as I move the scene, and most certainly are not billboarded.  

 

Can anyone spot my mistake? Any help would be most appreciated. Thank you.

 

EDIT - Update, I made the following changes:  I transpose the billboard matrix after construction, and changed my translation code to:

billboardMatrix.m30 = feature.position.x;
billboardMatrix.m31 = feature.position.y;
billboardMatrix.m32 = 0;
modelViewMatrix = CEMatrix4Multiply(inverseViewMatrix, billboardMatrix);

 

And this seems to produce billboarded text, as in the labels always face the camera, however, the labels are flush against the XY plane, rather than looking at the camera, so they are barely readable.  Still not sure how to fix this problem.

 

EDIT2 - I think I got it, by not normalizing the camera up vector, it seems to have fixed the issue.  It now appears to be properly billboarded.  I think the problem is my scale was being lost.  However, if anyone sees any errors in any of my math, please point it out, as I am certain that this is not perfect.  Thanks.

Edited by metsfan
0

Share this post


Link to post
Share on other sites

You have 3 choices to make this a bit more simple

1) build the matrix straight from the camera. This will always generally towards the camera, but for anything large you'll notice that it rotates relative to other objects as you rotate the camera, however it is good for things like text that you want to show up "ortho normal" to the camera anyway so they are legible.  They won't rotate as the camera translates, which can also be a nice property.

[ Camera.left, Camera.up, -Camera.at, obj.pos], as that will always have the same orientation as your camera and always be facing the opposite direction.

 

2) build the matrix using what is normally done with a library's "look at" matrix function. This will make your billboard behave like it is on a sphere centered at your camera, always facing the center.  They won't rotate when you rotate the camera, and won't be as good for text but better for particles.  They will however rotate as you translate your camera, so moving by one will make it seem to rotate around you.

at = normalize( camera.pos - obj.pos );

left = cross(camera.up, at)

up = cross(at, left)

"look at" matrix = [left, at, up, obj.pos]

 

3) if you want the object pinned on an axis (like a tree, that rotates on the Y axis only) then use technique 2, but use a constant for the "up" axis instead of calculating it (then ortho-normalize based on that axis instead of the 'at' like I showed).

Edited by KulSeran
1

Share this post


Link to post
Share on other sites

If it's supposed to completely face the camera, I see no need for special handling. Treat it like any other object and set the rotation part of the matrix to identity in the resulting modelview matrix.

 

Why? Because there is no camera, so after "moving everything the other way" you will always be at the origin and always look down negative z (by default at least). Ergo the rotation part is always identity and all you care about is the position.

 

In other words: why perform all those calculations, if you already know in advance what the result has to be? What you seem to be doing is to extract the cameras rotation matrix, then transpose (ie. invert it) and multiply them, just so they can cancel each other out and result in identity. That looks like more effort than

 

Vec4 pos = viewMatrix * Vec4(billboard. x, billboard.y, billboard.z, 1);

modelViewMatrix = {1,0,0,0,   0,1,0,0,  0,0,1,0,   pos.x, pos.y, pos.z, 1};

0

Share this post


Link to post
Share on other sites

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  
Followers 0