I often say that although many of the games we have played before seem to be 2D, they are actually 3D games-such as Blood Story and Double Dragon series, which have a set of three-dimensional spatial logic, which no longer makes the game The stage is limited to only the two axes of left and right movement and up and down jumping-the three dimensions of extremely free and open range of movement are believed to have left a deep impression on many players. In the last article, we have introduced this The physical part of this game is simple to implement. This time I will talk about the important skills of such games in rendering.
Obviously, in the 3D space simulated by 2D sprites, any object is not simple: a cube as shown in the figure has a oblique perspective(Or we call cabinet perspectiveMore accurate) modeling. Under such a perspective, if there is another sprite occluding each other, how should we deal with their rendering order?
Note: In order to simplify the description, the 3D space in this article assumes that all objects are z coordinateAll are the same, that is, “there is no height difference from the ground”.
Sorting between any two objects
According to our general simple thinking (for example, in the classic topdown perspective, such as the RPGMAKER series), who has the larger y value, Whoever gets closer to the screen, whoever should render further back, right? But from this perspective, it’s not that simple. Let’s look at an example:
As shown in the picture, according to the cross mark, we can easily find shari’s y coordinateSmaller than the coordinates of the cube, so she should be blocked behind the cube (rendered before the cube), right? But when she came to the other side, the situation changed:
As shown, shari’s y coordinateStill smaller than the cube y coordinate, But at this position, we want shari to occlude the cube instead of being occluded by the cube, so we need to consider more situations.
Obviously, any object in this world should carry its “base” information.As shown in the figure, the red parallelogram is the “base” information of the cube above, and the green is its height information (if you need some more detailed sorting, such as counting z axis, This article will not discuss it temporarily) With this information, we can determine the drawing order between any two objects.
We named the two objects to be sorted A and B respectively, and the upper edge of the base of A is called aTop, The lower edge is called aBottom; The upper edge of the B base is called bTop, The lower edge is called bBottom。
aBottom of y coordinateLess than bTop of y coordinate：
At this time, A is obviously behind B, that is, A is rendered before B.
aTop of y coordinatemore than the bBottom ofy coordinate：
At this time, A is obviously in front of B, that is, B is rendered before A.
Since our viewing angle here is a 45-degree diagonal line, we can easily place the bottom edge of the two objects y axisDistance added to aBottom The right end of the to judge, like this:
distanceY = bBottom.y – aBottom.y
(we use left with right Represents the left and right endpoints of a line segment)
aBottom.left.x > bBottom.right.x + distanceY
If this judgment is true, it is the situation described in the above figure: A is in front of B, that is, B is rendered before A.
Otherwise, it is the situation described in the following figure: A is behind B, that is, A is rendered before B.
Sort all objects in the scene
Ok, so far we can sort any two objects in the scene, then we can also organize and sort all the objects in the scene. The first reaction of many people is, isn’t it good to use algorithms like bubbling/selection/merge/quick sort to sort the objects in the scene? In fact, this is inappropriate, because the object occlusion in the scene has a topological relationship. If you directly use the linear table sorting method, you may swap a pair of objects to ensure their occlusion relationship and directly destroy the occlusion of another pair of objects. Therefore, our first step is to connect the objects in the scene that need to be sorted.
The end of the picture with the arc is the end of the ray, and the object at the end is rendered earlier (positioned further behind) than the object at the beginning.
Explain here,We only connect a pair of objects that need to be sorted (for performance reasons), So your display object may need to have a corresponding bounding_box Or something.
When there are enough objects in the scene and the occlusion relationship is sufficiently complex, it is not difficult to find that our object occlusion relationship actually constructs a directed graph. The directed graph can obtain a non-unique linear sequence through topological sorting, and the correct scene sequence can be obtained by rendering according to this linear sequence.
(The blue-green rectangle in the picture is used to judge the intersection/overlap of the elves bounding_box，DRAWIDX Is the rendering order value obtained after topological sorting)
In this way, the correct presentation order of the entire scene is obtained.
I believe we have all seen some interesting pictures of “visual illusions”, right? For example, three infinitely looping steps, three prisms obscuring each other, etc., are very interesting, but they are not interesting at all in game development. Obviously, when there are several occluded and occluded objects in the game scene, the directed graph we construct becomes a loop. The ring-forming directed graph cannot be topologically sorted, which leads us to no way to present the pictures in the correct order. The best way to solve this problem is to divide the object that easily causes the problem into two objects, so that one part is “specially occluded” and the other part is “specially occluded”, so that we can eliminate the directionality of our construction The ring in the diagram.
This discussion ends here, I wish you all a smooth development and a happy new year!