- Home /
Isometric tiles depth
Hey!
I'm trying to create an isometric game using isometric tilesets (rather than actually achieving isometry through the camera). Tiles are being placed on layers. Every layer is a single mesh. Every tile is a quad. Layers are based on object's depth - for example: grass = layer 0; bottom part of stone block = layer 1; top part of stone block = layer 2. Layers provide us some depth, but nothing really helpful (character and the wall).
The problem is I can't set rendering order basing on player's position because we can't really determine whether player is behind the wall or in front of it. (If each stone block was a single object we could set Z/sorting layer simply basing on Y/X position. But that's really impractical and performance hungry solution).
I've come up with an idea of rendering tiles column by column with layer's in mind. Here is what I mean:
All tiles in a column aligned with Y axis are being rendered (Y descending). After an entire column is rendered we jump to the next one.
If there are more layers present at given (X,Y), they are being rendered from the bottom to the top. So, if 3 layers use tile (1,2), we render them as follows: layer 0 (the lowest - ground), layer 1 (bottom part of the stone block), layer 2 (top part of the stone block).
Same as 2.
If there is an object (player in this case) on a given tile, it is rendered as if it was next layer.
Just like in 2 and 3 (to make thing clear).
Question: Is it a viable solution? I was thinking about using a shader that would somehow set tile's rendering queue basing on its position and layer level. However, I have never written any shader so I don't know if it is actually possible.
Is there any other approach I could take to solve this?
Any help would be appreciated (as well as pointing me in the right direction). Thanks!
Seems easier to just define the tile layers based on how close they are to the front. Group tiles using a diagonal line (left to right), since the tiles closest should always be drawn before tiles behind them. The character then just needs to have a layer higher than the diagonal he is standing on but smaller than the diagonal in front of him.
@maccabbe Well, I'm not sure if I understand you correctly, but that would require creating as many layers as there are rows (or even more). Also, what about standing behind 3 levels high wall? (3rd level block could be technically placed on tile over player, thus player will be rendered in front of it - wrong). Also the number of meshes increases greatly. I really like your solution though, for sure it's worth putting some thought into it.
Player is on tile that is layer 5 so his layer is 4. This causes him to be drawn before the tile he is on (layer 5) and the tiles behind him (including the tile and wall on layers 7)
Tiles in front of player are draw before player. This causes player to be "behind" wall on layer 3, otherwise no interaction.
Player's layer and entire walls are based only on the tile they are on. Even though the wall on layer 3 covers a tile on layer 7, the entire thing is layer 3. If the player was to step onto the wall on layer 3 his layer would be 2, just like if he were to step on a tile on layer 2.
Yeah, this solution is really neat, but I fear one thing - high number of meshes. Assigning different layers require different renderers which mean 1 mesh for every layer out there. I'm not sure if it poses a real problem, but I'd like to stick to the most performance efficient solutions. If I won't find any more efficient solution I'll use this one for sure. Thanks alot!
If you do every row then it will require more meshes. It probably won't be a significant number but of you run into problems you can do it for just the tiles near the character. In this case it seems like only tiles 7, 10, 11 (from your method) could block the player. So make make one mesh with all the tiles and put it behind the player. $$anonymous$$ake two more meshes (one for tiles 7&10 and one for tile 11). Then the displayed order would be map then player, then 7&10, then 11.