Billboard rendering without distortion?

I use the standard approach to billboarding within Unity that is OK, but not ideal:

`transform.LookAt(camera)`

The problem is that this introduces distortion toward the edges of the viewport, especially as the field of view angle grows larger. This is unlike the perfect billboarding you'd see in eg. Doom when seeing an enemy from any angle and irrespective of where they are located in screen space.

Obviously, there are ways to blit an image directly to the viewport, centred around a single vertex, but I'm not hot on shaders.

Does anyone have any samples of this approach (GLSL if possible), or any suggestions as to why it isn't typically done this way (vs. the aforementioned quad transformation method)?

EDIT: I was confused, thanks Nathan for the heads up. Of course, Causing the quads to look at the camera does not cause them to be parallel to the view plane -- which is what I need.

-

I'm confused by your question because in a standard perspective projection, drawing a billboard parallel to the view plane does not introduce distortion. It's equivalent to blitting the image to the viewport with some scaling, where the scaling depends on depth (perpendicular distance from the view plane).

The "distortion" you're seeing might happen if the system is actually orienting particles to face the camera rather than the view plane; that causes skewing near the screen edges. Or, you might be seeing that the sprite's scale changes as you rotate the camera, since when distance is measured to the view plane rather than to the camera, the sprite gets "closer" and hence bigger as it goes offscreen.

-
@NickWiggill I'm not familiar with Unity specifically, but if you want to have the quads face the view plane rather than facing the camera, you essentially set the quad's rotation matrix equal to the camera's rotation matrix. You might need an extra 180 degree rotation in there depending on how the quads are constructed. – Nathan Reed Apr 12 '12 at 22:28
Ah, OK. Thanks Nathan, I'll give that a shot. – Arcane Engineer Apr 12 '12 at 22:28

I believe you can set the top 3x3 matrix (in column-major speak) to the identity to do this. I don't see any reason why you couldn't do this in the shader, but you might be doing more work that way. You'd lose scale (in your xformation matrix) this way.

Edit: this article was helpful to me for billboard-ing and imposter-ing:

http://www.flipcode.com/archives/Billboarding-Excerpt_From_iReal-Time_Renderingi_2E.shtml

I don't know how conventional this is, but I call it "impostering" when perspective is maintained and "billboarding" when it is not.

-
I realised something. I'm using Unity iOS/Android, and some of the older devices are OpenGL ES 1.1 -- thus fixed pipeline. So to do it without shader is key here. How would I go about this without doing it in the shader? – Arcane Engineer Apr 12 '12 at 22:19
That's probably the cheaper way to do it anyway. In my code, I have a flag on my sprites that dictates whether to billboard or imposter prior to making draw calls. When this is the case, I simply take the current matrix, set the upper 3x3 to identity, and then update the current matrix. – stephelton Apr 12 '12 at 22:23
Ah... appreciate the extra detail but since I don't have access to GL calls (Unity abstracts that away), I think I'm pretty screwed on this approach. – Arcane Engineer Apr 12 '12 at 22:24
You can't get or set the current matrix? I've never used unity... If not, maybe try searching "unity billboarding" or "unity impostering" – stephelton Apr 12 '12 at 22:25