Puzzling 3D Sprite + Tile depth sorting behavior (SOLVED)

So I’m currently using a 3D perspective camera overlooking the world at a 45 degree angle. Everything renders fine up until the player sprite crosses into the positive Y coordinate space and the player sprite and tilemap immediately swap draw order.

[Here] is an online build showing the issue. Use WASD to move.

The player and the tile map are on 1 and -1 z coords, respectively. The problem persists regardless of camera angle unless I move the camera back fully overhead (i.e. default head-on ortho projection).

How do I fix this? Custom tile material? Render script?

Not sure why. @ragnar.svensson?

Default behaviour is back-to-front sorting relative the camera (or in fact view and projection matrices as used by the render script). The position of the tile map is not a good representation in your case, since as soon as the player-position is behind that point, the player is drawn behind. I would recommend you to draw the player and tilemap separately by assigning a new tile material with a different tag to the tile map (or player).

4 Likes

Would models display the same sorting issues? I can separate the character and environment into different materials/predicates, but then I wouldn’t have proper occlusion if the character is behind some object in the environment, right?

Is sorting something I’m able to change in the engine?

I would suggest you do the separation on ground vs. player+env.props. The player and props should be sorted without issues, given that they are roughly the same size or large props prevent the player from moving around in such a way that the clipping occur. If you would have a large building, that would need to be a movement obstacle as well to separate the graphics while the player crosses the position along the z view axis. This is surprisingly hard to describe with words, hope you understand what I mean.

1 Like

So I came up with a tangential workaround.

I puzzled out that the aformentioned camera-relative sorting is relying on the game object’s pivot/origin to determine occlusion. In the online build above my tilemap’s origin is in it’s visual center, and the moment the player moves into the Y+ space, the tilemap’s pivot in camera-relative space is now in front of the player object’s pivot.

So I redrew the tilemap with the origin instead occupying the upper-left corner. Like so:

Now the player’s pivot never crosses the tilemap pivot’s X/Y coords and the sorting works.

For anyone reading this, make sure you’re mindful of the game object’s pivot position for proper 3D sorting, not the graphics.

For example, to make the player properly occlude/not-occlude with this house sprite:

I made sure to offset the sprites for the player and the house so that their pivots would be at their respective bottom centers, this ensures the player doesn’t float in front of the house when passing closely behind it.

It’s not perfect, there are some corner cases where the pivot position is still not indicative of occlusion, but the overall crisis has been averted. That said I hope future versions of Defold support more conventional visibility sorting.

5 Likes