2D sprites in 3D scene without billboards
Well, maybe this still counts as billboarding, but not quite the traditional way.
I have a 3D scene with the camera looking down at the ground at an angle, pretty much a basic 3/4 perspective. I want to use 2D sprites rather than 3D characters. But using regular spherical billboarding to render the sprites creates some problems. Since the billboard quads are put into the world at an angle they don't really play nice with some of the other 3D elements of the scene. For example, if a sprite gets too close to a fence it causes problems. If the sprite is in front of the fence the upper part of the quad may cut into part of the fence. If the sprite is behind the fence the lower part may do the same thing.
But what if I could render the sprite using a completely vertical quad? Since the fence (and all other troublesome objects) are pretty much vertical too that would solve my problems. The sprites could stand in front of the fence, behind the fence, whatever. But how do I do it?
I figure I need to do something like this:
The blue represents what a billboarded sprite would look like. It's directly facing the camera. The red line represents what I want the sprite to look like. All I have to do is project the points on the blue plane into the red vertical plane and make sure the points are scaled to adjust for distortion so that to the camera the sprite looks the same.
So... how do I do that? Has anyone tried this before?
You mean just create a vertical quad with my sprite as a texture? The problem with that is since the camera is looking down at it at an angle it's a little bit distorted.
I can make it look better by manually adjusting the scaling of the quad to compensate, but I want it to happen automatically.
I can make it look better by manually adjusting the scaling of the quad to compensate, but I want it to happen automatically.
It seems to me that you only have to intersect a plane with a frustum. Get the 4 points, and draw the quad (probably with the heavy use of homogeneous texture coordinates to avoid the well-known trapezoid-texturing issue).
I guess your frustum depends on the aspect ratio of the sprite texture, and its distance from the camera.
Is the pitch of the cam adjustable? If so, your sprites will distorted anyway (you can't see the top of their head even if you are looking completely down).
If not, why not using a pre-calculated/hard-coded trapezoid?
I guess your frustum depends on the aspect ratio of the sprite texture, and its distance from the camera.
Is the pitch of the cam adjustable? If so, your sprites will distorted anyway (you can't see the top of their head even if you are looking completely down).
If not, why not using a pre-calculated/hard-coded trapezoid?
If you look at the illustration you drew, you can see that the sprite up vector is just the world up vector, the right vector is the camera right vector and the look vector in the negative of the camera view direction vector. Using these vector you can construct your sprite(billboard) that always face up in the world. It will look weird as you approach the sprite from above because you are going to see that its just a 'sprite'.
I might be wrong, but maybe with a simple texture projection from the camera to the wall you´ll achieve what you want. You would first draw you billboard/billboards without the wall behind to a texture, then project the resulting texture on the wall. Depending on how many billboards you want and the specific use/look you are aiming for, this might be a better solution.
Quote:Original post by ArKano22Or an other idea (might be just the same as ArKano22's, but anyway) let your character be a simple quad, bigger than the character. It would be that semi-aligned quad stuff (like tree billboards, so the up axis is fixed). And the texture is simply the automatic eye-mapping stuff. I can't think of a way to calculate the tex-coord offset, but maybe that's enough for start.
I might be wrong, but maybe with a simple texture projection from the camera to the wall you´ll achieve what you want. You would first draw you billboard/billboards without the wall behind to a texture, then project the resulting texture on the wall. Depending on how many billboards you want and the specific use/look you are aiming for, this might be a better solution.
After thinking about this a bit, it seems to me that all I'm really trying to do is render the sprite using a plain ol' spherical billboard, and then once the billboard vertices are in clip space I'm adjusting the depth of each vertex, so the billboard ends up aligned to the Y axis.
Here's an algorithm that I think will do what I want:
I could easily do this in a vertex shader. I could precalculate j and send it in as a parameter.
Does all that make sense? Am I on the right track? Or am I crazy?
Here's an algorithm that I think will do what I want:
for each sprite vertex: p = the vertex position in view space (before perspective transform) p' = the vertex position in clip space (after perspective transform) j = a vertical plane facing the camera (in view space) p2 = point at intersection of j and a ray pointing to p p2' = p2 transformed to clip space p'.z = p2'.z
I could easily do this in a vertex shader. I could precalculate j and send it in as a parameter.
Does all that make sense? Am I on the right track? Or am I crazy?
Er...
Is it working or not?
I believe in the philosophy, that an idea is not crazy, there is no 'right-track/way'. Does it work or not? I guess you won't have thousands of characters, so I wouldn't worry about performance (BTW, my solution seems simpler :P )
BTW for your idea: I would create a 1D texture with the depth offsets, which would only change if the pitch of the camera changes. The texture itself is mapped just like the sprite texture (same texture coordinates). You can even use a 2D depth offset texture too, so your sprite have some "depth", for lighting etc.
Of course, I don't do shading yet, so I don't know how problematic the offset-texture change would be. But maybe you could use a constant texture, with some modifier calculated with some fancy math ;)
Is it working or not?
I believe in the philosophy, that an idea is not crazy, there is no 'right-track/way'. Does it work or not? I guess you won't have thousands of characters, so I wouldn't worry about performance (BTW, my solution seems simpler :P )
BTW for your idea: I would create a 1D texture with the depth offsets, which would only change if the pitch of the camera changes. The texture itself is mapped just like the sprite texture (same texture coordinates). You can even use a 2D depth offset texture too, so your sprite have some "depth", for lighting etc.
Of course, I don't do shading yet, so I don't know how problematic the offset-texture change would be. But maybe you could use a constant texture, with some modifier calculated with some fancy math ;)
I finally have something mostly working. I was able to get the algorithm above doing what I want (with a few little changes, like p'.z = p2'.z * p'.w / p2'.w so that the subsequent perspective divide still works). The only issues I'm having is that things kind of fall apart when a sprite gets near the bottom of the screen, but that's to be expected, I guess. I'll try adjusting the camera to avoid those steep angles.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement