Multi-Directional Billboards

I am developing an old-school fps framework and having a lot of trouble working out billboards.
I have a face that always faces the main camera on a single axis, that one’s easy enough.
The issue I have now is that I cannot seem to work out how to dynamically work out what sprite to show.

I am using Z+ (forward) as the facing direction, and need to (if using 4 directions, front, right, back, left) display front between -45 to 45, right between 45 to 135, back between 135 to 225, left between 225 to 315 depending on what angle the main camera is viewing related to where Z+ is facing.

Maybe this isn’t the best way of describing it, essentially I want to show the front sprite (sprites[0]) when the main camera is somewhere between -45 and 45, in relation to where Z+ is facing, faking a 3D look.

The issue is, I want to do this in a more dynamic way, dividing the angles (360) into equal number of parts depending on how large the Sprites array is.

Each time I tried this, I got stuck on working out the viewing angles for this.
Anyone done this before, or know any way to do this dynamically?

i have some resource links for directional sprite billboards here:

in shader i used this math,

sheet

3 Likes

Absolutely perfect, thank you very much!

Hello, I’ve been trying to solve the same problem. I found this post and tried to replicate the solution but ran into an issue where the sprite has parts of the art missing:

I used the same shader script as linked. When I rotate around the character the sprite changes appropriately, it’s just the image comes out all messed up.

Was wondering if either of you had this issue and knew a fix, or possibly something I’m missing

havent seen that kind of issue before… are you on pc?

*added issue here if anyone has info,
https://github.com/unitycoder/DoomStyleBillboardTest/issues/14

Yes, the project is running on 2018.4.20f1. Not sure what might have caused it

Ok, so because I am using Unity 5 (pro license) and had problems with compatibility with my project, I decided to write my own solution to this, but I have a few problems with it.

I have this running in a script, not a shader so my approach is undoubtedly different, but I’m having a few very perplexing issues.

So, the sprites go into the Sprites array in the slots starting from the front, and working clockwise from the top down (Front, Right, Back, Left). This approach seems to work well with the exception of Sprites[0] (front) which never seems to be shown, and I can’t for the life of me work out why.

Any ideas what I’ve done wrong?

6187713–678327–ArcaneMultiBoard.cs (3.83 KB)
6187713--678330--Directions 1.png

i suspect this is your problem

if (currentPos >= (startEndPos_.startPos - 360) && currentPos <= startEndPos*.endPos)_
when this code is hit in the i == 0 case its checking currentPos against a negative, so you lose half the range for that first sprite there.
there is a lot wrong with this code. the approach uses a lot of logic, and storage where next to none is needed (and thats before looking at the questionable approach to swapping the textures…)
if you want to map into some array of length n from some angle 0…360, use just arithmetic instead of conditionals, loops and data? remapping one range of numbers to another is very useful in general.
i’d also suggest always always working in radians. always. always. degrees are the devil. however i will use degrees to keep things clear…
do this, starting with the angle you have.
add 360/(2n) degrees - this moves the start point where we want it, so zero degrees/radians and our array align, -360 if it goes over or equals 360 - this keeps things in bounds
now divide by 360/n - or multiply by n/360 - this reduces the numbers so that 0…1 is each segment
take Mathf.FloorToInt of this…
you have a number from (inclusive)0-n(excluisive), i.e. the index into the array, no branches, loops or stored array of ranges.
_
… for the case of 4, you could use dot products with forwards/left to do this much more simply depending on which has the bigger magnitude and the sign you can work out which one you need.*_
i hope this helps, or the next person who looks here.