Overview
3D Sprites (also called billboard sprites), are simply 2D sprites in 3D space, with their orientation always facing the camera. Some prime examples include the trees in Super Mario 64.
There have been past tutorials in earlier versions of GameMaker that covered this, but the games they were implemented into were usually Doom-like games, with no movement in the Z direction. This tutorial will be applicable in any 3D game made in GMS2.
Algorithm
- Get the current view matrix.
- Set the top-left 3x3 of that matrix to its transpose.
- Set the bottom-left 1x3 of that matrix to the object’s X, Y, and Z position.
- Set the world matrix to that transformed matrix.
- Draw whatever you want. (Make sure everything is anchored around (0, 0))
- Reset world matrix when all done.
Code
/// Function
function matrix_transpose(_mx) {var _m0 = argument0;
var _mx2 = _mx;
for (var _i = 0; _i < 3; _i++) {
for (var _j = 0; _j < 3; _j++) {
_m2[_j * 4 + _i] = _mx[_i * 4 + _j];
}
}
return _mx2;
}
/// Object Event: Draw
var _mx = matrix_transpose(matrix_get(matrix_view));
_mx[12] = x; _mx[13] = y; _mx[14] = z;
matrix_set(matrix_world, _mx);
draw_sprite_ext(sprite_index, -1, 0, 0, ...);
matrix_set(matrix_world, matrix_build_indentity());
Example
As you can see, these sprites are facing the camera the same way, no matter the angle, with no visible skewing or stretching.
Final Thoughts
With this current code, on my PC, I can have around 2000 of these instances in a room, running at a constant 60 FPS. There are obvious ways I can optimize this code in the future, like only accessing and transposing the view matrix only once per frame, instead of once for every instance per frame. This was just my quick and dirty method to get it to work; I’m gonna let you refactor the code however you want.
That’s it for my first GameMaker Studio 2 tutorial. Thanks for reading! -AH