Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Tile Map Accelerator - High Performance Shader Based Tile Map Renderer

Discussion in 'Assets and Asset Store' started by r3eckon, Jul 10, 2019.

  1. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506

    Tile Map Accelerator is a shader based tile map renderer capable of delivering stellar performance on massive tile maps thanks to a technique known as "Texture Bombing". Get 1000+ FPS and the lowest possible render thread times for even the largest of tile maps!


    See the difference between a Native Tile Map VS Tile Map Accelerator. Tile Map Accelerator can deliver better performance than a native tile map that is 8 times as large. While Native Tile Maps usually destroy FPS when zooming out over the whole map, TMA handles it with no problem!


    The asset is more than a powerful tile map rendering shader. It also includes a bunch of utility scripts to help you getting started. Some of those utilities include tile type based collision / trigger detection, mouse cursor tile map interaction, active layer baking script to allow for runtime edits of tile maps as well as a simple top down 2D character controller.


    The asset also includes an integrated version of AutoTileset Generator, a free utility allowing users to quickly turn AutoTile atlas files into individual transition sprites. It has been used to generate the simple grass to water transition tiles used in the screenshots & included demo scene.


    The asset has released to the asset store at a starting price of $20 but will be continually updated with new feature and will likely see price increases as features are added. Below are some links to the asset store page and the demo build. To finish up, if anyone has any comments or questions about the asset, feel free to leave a reply in this thread or contact me directly at r3eckon@gmail.com.

    TMA 1.2 NOW SUPPORTS ISOMETRIC RENDERING



    Try WebGL Demo Builds :

    Updated Isometric Demo ( Might Not Load In Some Browsers )

    Multi Layer Demo | Auto Chunking Demo



    Download Windows 64 bit Demo Builds :

    NEW RTS GAME TECH DEMO ( With Modding Support )


    V2 Isometric Demo ( Map Size x2 WebGL Version )
    V2 Isometric Demo Nvidia Compatibility Mode


    Default Square Tile Map Demo Build





    Tile Map Accelerator Asset Store Page

     
    Last edited: Dec 17, 2020
    AidanofVT, Grizmu and joshcamas like this.
  2. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here is a video demonstration of map wide animation, a feature I have just added to the asset that will be featured in version 1.1 of the shader.



    It works by creating multiple frames of animations by duplicating the main tile map mesh a bunch of times and by using the [PerRenderData] tag assigns a slightly different tile set to each "frame" or mesh rendering the tile map. By storing animation frames as extra tile types and using a simple script to switch between frames depending on a set animation framerate and style, can animate tile types on a map wide basis, although it may be hard to tell from a very zoomed out view.
     
  3. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    After a few weeks away from work I have finally been able to implement Auto Chunking to the asset! This new feature allows for basically seamless map edit baking thanks to the splitting of the map rendering mesh into multiple sub meshes or chunks. As you can see below, the map is divided into smaller meshes each rendering a portion of the full map.


    The amount of chunks generated by this system can be tweaked to work with any tile map sizes. Of course, since the main role of this system is to make edit baking faster, it may not be beneficial to use it on map sizes below 512. The above map is 2048 x 2048 and 8 x 8 chunks are used, each being 256 x 256 tiles in size.


    This feature as well as the animation controller will be releasing with version 1.1 of the asset. ETA on release is currently before the end of the month :)
     
  4. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here is a quick video to go with the last post, showing off the auto chunking feature in action. Active Change Baking happens when the Live Edit Count goes to 0. Both times this happens in the show off, the framerate only dips to about 500 for a few frames, which is still very comfortable and will fit perfectly with max FPS values. Tile map size is 2048 x 2048 and the amount of chunks used is 8 x 8, which means each chunk contains 256 x 256 tiles.


    You can also observe the triangle count increasing and decreasing as the camera is panning over now optimized quad based renderer objects, which use quite a few triangles less than the typical mesh plane does. Auto Tiling of grass to water transitions is disabled for this show off since it still happens over the full map and induces a bit of lag, but it should be simple to allow auto tile passes on certain chunks only to speed it up.
     
  5. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    I'm really digging what you're doing here. What's next?
     
    r3eckon likes this.
  6. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Thanks! I'm currently working on transparency so that multi layered rendering is a possibility. This will allow for things like player walking behind certain elements, sprites containing glass or other semi transparent colors, multi layer rendering for things like only drawing certain floor of an office building depending on player position and also isometric rendering support.

    That last one might take a while to work out, as I'm still a bit confused on how I'm going to handle sprites that take lots of isometric tiles. Extra full tiles on other Z layers is fine, it's the half tiles that are going to be a bit of a challenge since my sprite fetching code is made to work with full square tiles. Also, the only example of isometric texture bombing I have found was handled in a way that did not allow "tall" isometric sprites, which span more than a single tile.
     
  7. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    Just picked it up (a bit later than I thought I would) but eager to play with it.
     
    r3eckon likes this.
  8. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Awesome! If you have any issues or questions be sure to let me know!
     
  9. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here is a quick video showing off the latest addition to the asset : Multi Layered Tile Map support.


    To allow this, a variant of the core shader using transparency was first created. Then, a bunch of modular fence sprites with transparent background have been added to the tile set. A new manager script is also used to handle initialization and control of multiple tile map rendering meshes. This script is where, for example, the "ceiling" layer of houses on the tile map would be disabled when the player enters a house. Finally, a simple multi layer map generator was created, simply using the original map generator and adding random length fences at random positions.

    Here you can see how in 3D there is a visible "height" difference between the fence rendering layer and the background rendering layer. First image is what it looks like from orthographic 2D perspective.



    Even though the layering currently works directly as an extra layer of tile types which the player can interact with using colliders, this system could easily be used for pure rendering, perhaps with parallax effects added. Of course, since this system MUST use a different tile set AND tile map data for each layer, it is not recommended to use multiple layers with huge maps only to render some objects on the above layer. For this particular use case, it would probably be more efficient to locally render objects above the player instead of using an entirely new tile map layer.
    Also coming in version 1.1 is a simple "Template" editor GUI that can be used to create multi layer ( or single layer ) tile map templates. Working much like my dungeon generator's room template editor, except sprites are used directly in the editor instead of arbitrary colors representing tile type values. The "origin" position will essentially be moved on top of the selected point to place the layer. Once again this is similar to my dungeon generator, which uses this origin point as the "entrance" of a room template and attaches the room to a corridor using that position.


    Of course, the main goal of this feature is to allow easy in editor creation of complex Multi Tile Objects. The editor GUI also allows the use of alternate tile sets while in this editor. Tile sets files created using the tile type manager GUI can be directly opened and basically previewed using this editor.


    I will most likely be back before update is sent for validation to show off the random placement of templates on tile maps :)
     
  10. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    While I applaud your latest round of changes, the part that makes me nervous is having large or complex objects as multiple tiles per object. From an asset preparation perspective, it sounds like a nightmare. I'm also concerned that animating objects that span more than one tile would be difficult. Take the windmill example. You have the base structure, and the rotating blades. It seems to me that this would be difficult with your system?

    I'd love to see an example of how it works. Perhaps another video?

    PS: Any chance of a webgl demo?
     
  11. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    My house example is using modular pieces. The fences are also modular but much more simple than the house. I'm personally going for a fully modular approach in tileset creation because we have a limited amount of tile types to play with, currently 2048, so I'm trying to reuse anything I can as much as possible. However for large animated objects there is really no reason not to just use an independent game object. Although it would be entirely possible and honestly not that time consuming to split those objects up if they have been created with the right the tile size, the sheer amount of tiles required to perform the animation would probably be quite high and fill up the tileset with non modular, non reusable tiles, used exclusively to draw a single object that always looks the same.

    The process I went through to make those sprites is pretty simple, I don't know if a video is really warranted. All that must really be considered is repeating patterns, like the wooden clapboard on the house. Since tiles are 16 x 16 pixels I can only create looping patterns that span an amount of pixels that can divide 16 into a whole number. I used 4, so the "plank" part is 3 pixels high and then a single pixel high dark line is added to separate the planks. Starting by making the "tileable" sprite then gives you the start point to create other types of parts that can attach to this one. For learning about all this, you really should go check out some better artist's tutorials as my art skills are really not the best.

    Anyhow, I'll do some testing with WebGL and see if I can get a demo up and running. I'll post the link here once I got it hosted.

    Edit : I have now hosted two demo builds on itch.io, both work flawlessly and run very well for me on my two Windows devices so please let me know if you encounter issues. I will probably upload more demo scenes like the animated scene & other map generator styles later on.

     
    Last edited: Aug 28, 2019
    SirStompsalot likes this.
  12. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here is a quick video demonstration of the Tile Templates being used with the map generator. There are 3 templates used in this video, being picked at random.

     
  13. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    Looking good! Can't wait to see what comes next!
     
    r3eckon likes this.
  14. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    I have just updated the Multi Layer demo scene on itch to show off the multi layer template stamping with the house templates. This feature was slightly improved since the video and now checks the map data for "incompatible" tiles before applying a template. I also added a few templates and fixed an annoying quirk where the camera would get stuck when reaching a border.

    This week I will be bug checking the new features I have added to the asset since initial release and finish up the documentation regarding new features to get ready to send in version 1.1, so even though I am still open to feature requests anything new will most likely be added in a future update.
     
    SirStompsalot likes this.
  15. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    Isometric support.

    Yaknow, just saying. ;)
     
  16. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Yeah isometric rendering is definitely on my list for next version! The basics of it are simple enough to implement but I'm pretty much convinced that "tall" isometric sprites will be a bit of a challenge to get working with this shader, so it might take a little while.
     
    SirStompsalot likes this.
  17. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Version 1.1 has released a few hours ago! I have already been made aware of an issue with Unity 2019 where the animated demo scene does not correctly render extra animation frames. The issue is caused by something about the engine I have no control over causing animation tile sets to be filled with transparent sprites even though I logged the name of the files being added as well as pixel color data to check that they are not, in fact, transparent.

    This demo works as expected on 2018.3 and a workaround has been found for 2019. Basically I just moved some code from one script to the other after exhausting most other options and it immediately worked, so my guess is this is some weird script ordering issue since this code was usually called by that very script but executed from a different component on an instantiated object. I will most likely need to raise an issue ticket to see if anyone at Unity can find out what causes this behavior.

    In any case, the workaround is going to be sent in a few hours and should hopefully release soon!
     
    SirStompsalot likes this.
  18. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here is the latest feature added to the asset, a simple character animator script for the top down controller. It works in a similar manner to animated tile maps, but instead selects the correct sprite(s) for each 8 Directional and State combo. The current animations states are just "walking" and "idle". This system can work with any 8 directional character spritesheet by simply splitting it with the Unity Sprite Editor and then specifying which "subsprites" should be used for a particular state.


    As you can see on the right side, right now I'm only using two sprites of animation running at a slow framerate for the "walking" states. The Top Down Player Controller script has been updated to send keyboard input based player direction + state to the animator script, which uses this information to use the right sprite collection. More states can be added, and the system can easily translate to other movement styles like sidescroller / platformer.

    I'll probably be posting a video showing off the whole feature once it's finished, as I still need to add "Z awareness" for the player to correctly walk behind houses, which I believe will also play a great part in correctly implementing isometric and sidescroller perspective layering.
     
    SirStompsalot likes this.
  19. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here is the automatic layering system at work already! This was a lot simpler than I thought it would be to implement. The system is also completely independent from the character controller script, which means any npc, monster, mob, boss, movable object in your game world can use the feature! You can also see the 8 directional character animator at work in this video.


    Pay attention to the top right of the screen to see what's happening behind the scenes. The Z position of the player object is automatically set to be behind the layer currently being checked if the tile data directly above the player pivot ( and collider ) is not transparent. Since I'm only checking the center tile, the player can still glitch above edges of objects that it should be behind ( happens once in the video ). I'm gonna need to add a way for the system to detect when the player is currently near the edge of two tiles, and check those two neighbors. Larger entities will probably need to check the full tile neighborhood in order to correctly handle the layering.
     
  20. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Yesterday I got around to reworking the automatic object layering system to both optimize the speed at which check happens and to implement a way for the layer check to happen on a large area. Instead of checking all layers, the system now creates a low overhead array containing the first non transparent layer of each map point upon generation. Since this uses slightly more memory, I will leave this optimization as a setting that can be toggled on or off.


    The two "range" values are then used to loop over this array using the current map tile where the object is located as the center. So a X range value of 1 will go check up to -1 and +1 tiles away from that center position, allowing the player to correctly be rendered behind top layer content even if the pivot of that object is not on the same tile. Larger entities like for instance bosses that span a large area of tiles can simply use a higher range to make sure they properly layer.

    The multilayer demo scene has also been updated to show off the new auto layering feature!
     
  21. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    One thing I dug about the updated demo is that the player graphic seems to be 2 tiles tall. Does this remove the restriction that each graphic asset has to be 1 tile?
     
  22. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    The sprites used to build the tile map, those rendered with the shader, still need to fit inside one tile. So since houses are tile map bound objects they are still being built using modular sprites. Meanwhile there is no restriction on the size of game world entities that are not rendered using the shader. I'll most likely add a simple script that allows a manually set "layer" parameter on static objects that aren't bound to the tile map to allow moving objects to perform auto layering checks on non shader objects. This ties in with moving object to moving object layering which I still need to implement.
     
  23. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    Ah, that makes sense. Thanks for the update!
     
    r3eckon likes this.
  24. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    This is another quick video demo of the latest work done to the asset, this time testing object to object auto layering.


    Overall this is just your average Y position based layering placing objects that are higher on the Y axis "behind" other objects in the world, however a few updates were made to the multi layer system to enable this. Most importantly the Z position of each tile map layer besides the background is now calculated based on the amount of objects in the scene and two z axis spacing parameters. Layer Spacing is the minimum space between each layer while Object Spacing is the amount of space between objects.

    Then, objects use a simple 2D bounding box defined in editor to check for collisions against a list of other nearby objects. If the current object is supposed to be "behind" an object it is colliding with, the current object is also placed on the same tile map layer before being placed behind the colliding object. This allows the small character can walk "behind" the tall character that's behind a house even if the small character doesn't go behind the house tile.
     
    SirStompsalot likes this.
  25. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Since the next feature I'm adding to the asset is most likely going to be isometric rendering support, I'm currently working on a shader that can handle this type of rendering. Here we have the same shader code used to render the square grid, set in a UV space being rotated by 45 degrees. This creates a grid of diamond shaped tiles and from there a bit of scaling on the Y axis should be enough to create an isometric projection.


    While I feel confident that isometric rendering with proper layering is entirely possible with the shader, I'm still unsure of how to handle the storage of isometric tiles. The core of this issue is that isometric "tiles" are not like regular square tiles, so they cannot just be stored in the Texture2DArray and easily fetched for rendering. For a while I thought about creating a tool that just rotates isometric tiles into square tiles, but this would most likely induce lots of graphical artifacts, and rotating pixel art usually doesn't result in clean looking sprites, so I'd rather not have to go that route.

    The best option I can think of would be to just store unrotated isometric tiles in square texture space and, using some more shader magic, offset every other row of the tile map on the X axis so that there is no empty space between tiles which will give the impression of an isometric grid. This would probably require a completely independent tile map interaction script to handle mouse interaction and collision. The initial version of the isometric rendering feature may come as a lone shader with few support scripts so that I can release all of the other features I have added since the first version.
     
    SirStompsalot likes this.
  26. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    After spending a bit more time working on isometric rendering, I've come to realize that the shader I previously thought would be optimal to handle this task actually set a lot of annoying unavoidable limitations when it comes to asset creation. I have therefore switched my focus to another technique, this time using typical rectangular UV space, which will greatly simplify the asset management and storage process.

    Basically, the challenge of purely 2D isometric rendering in shader is that we cannot stick isometric sprites on a single grid of same sized rectangles like regular tiles. Tiles on odd rows and columns simply do not fit within this grid, instead residing on the points where four corners meet. The solution : using two grids on the same tile map renderer.


    This is Grid A, the regular grid space for tiles on even rows and columns. Note that the grid space is set to handle isometric sprites which are twice as wide as they are tall, which is what I assume to be standard after reading through a few guide on how to create isometric sprites. The colors used within the cells are simply to show that the UV space within cells runs from 0,0 to 1,1 with color red and green tied to the X and Y parameters respectively.

    Of course this single grid isn't enough for isometric. This is why we need to use Grid B :


    This is pretty much the same grid, except it is offset by half a cell in both directions. Some of you may already notice how this places the center point of each individual UV space of this new B grid on the points where four corners of A grid cells are meeting. This now allows us to render anything we want on both grids, and by using the max() function we can combine them together and use a simple lozenge shape to visualize how everything fits together :


    Note that the lozenges are not filling the area they can take simply to make it easier to tell each cell apart. Sprites would take up the entire space. One of the advantage of this shader compared to the one I previously posted about is that isometric sprites can easily be stored in Texture Array with no extra steps, as well as the fact that UV space is preserved locally for each cell instead of being rotated, which I'm sure would have made things a lot more complicated down the line.
     
  27. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Seems the isometric variant of the tile map shader is working as intended! This was rather straightforward to implement and in the process I also managed to find and fix a bug with the Texture2DArray being created with bilinear filtering instead of point filtering making small sprites become blurry as the camera zooms in.


    Here you can see the edges of the tile map being automatically trimmed and set to be transparent. Right now I'm only using white noise for tile map data, so next step is likely going to be the implementation of a simple isometric map generator, map interaction and other necessary scripts. Layering will also need a bunch of utility scripts to work properly, since rendering "tall" isometric sprites won't be as simple as it would be on a regular isometric map.


    One thing that's worth nothing with this system is that the isometric tiles must be pretty much perfect otherwise gaps will appear. Many of the guides I've found on how to create isometric tiles used wrong sizes or sizes that would require weird grid offsets. While I'll be including the working templates with the asset, an easy way to build a correct one is to create an image that's a quarter the size of the wanted tile and split it in half diagonally, making sure that both halves contain the same amount of pixels like shown in the selected area :

     
  28. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    Hey @r3eckon !

    This is looking super promising. One approach that I'm currently using with Unity's tilemap (regarding the gaps issue you mentioned) is reducing the tilemap's cell padding to something small like 0.008, would that approach work here? It would add a fair amount of overdraw, not sure if that's an issue.

    I know we talked about potential isometric support back on reddit. Were you able to test with any of the test files I sent you? Were those helpful?
     
  29. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Hi ! So far I have only been able to test it with my own sprites, but once I got to test a bunch of "tall" isometric sprites of my own to see how this all works I'll be testing it with those you sent me and other iso tilesets I can find online.

    For the padding part, I'm aware that lots of people will likely want be using different styles of isometric tiles with the asset so I'll most likely expose a few shader properties to tweak padding and offset values which should allow us to customize the A and B grid center points as needed. Although I'd recommend following the model I'll be including for people who start from scratch and haven't created their art yet so everything just works out of the box. Some sprite preparation will ultimately always be required for most isometric tilesets to work with this shader, for instance the splitting of tall sprites to add any parts of a sprite that the player can walk behind on another layer.

    As for the overdraw, a core part of the shader is the fact that for any point on the map it always ends up going for the maximum color value. Transparent pixels are of lowest priority to ensure transparent parts of the sprites are not rendered on top since what the shader is technically doing is rendering lots of rectangular sprites on two overlapping grids which causes constant overdraw. I know very well that while this works to clip transparency, this may not be optimal for all overdraw situations.

    Note that I have not really tried this out yet so this is just speculation, but it's probably going to be worth it to spend a bit of shader performance on logic that allows certain tile types to have priority over others no matter which color they are to allow a sort of type based "painter's algorithm". This priority could also simply be based on tile position, or even a randomly generated value as the GPU gems on Texture Bombing shows. Maybe there's also a mathematical / shader optimized way of doing this I'm not seeing right now to avoid the conditional logic or just another better way to handle the overdraw all together, but I can't know for sure until I start trying things out.

    In any case, I'll be posting more concrete info about those topics once I get some more testing done!

    Edit : fixed wrong article link
     
    Last edited: Oct 22, 2019
    SirStompsalot likes this.
  30. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here we go, isometric support is up and running! Here is a video demonstration using two isometric sprites I've quickly created, being a simple cube of and a building. The bottom of the post also contains some screenshots.


    One thing to note is that I'm still unsure whether or not it will be possible to allow game objects to walk in between isometric sprites purely with tile map layers due to the fact that most of the layering / fake 3d effect is done using one mesh. Perhaps I'll think of a way eventually, maybe by somehow passing the player sprite rendering to the shader so that it can handle the layering or using pooled game object based sprites. Also, since isometric rendering sometimes requires up to 3 different sprites to essentially "merge" on a single tile, this shader must read from 3 different tile map data textures, which will increase the delay for edit baking on large maps.

    Despite those limitations and perhaps most importantly, the shader remains basically perfect at what it was originally intended to do which is to render massive (isometric) tile maps at high FPS. Again this has only been tested on my desktop GPU so mobile performance remains to be tested.







     
  31. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    I must say, this is looking really impressive.
     
    r3eckon likes this.
  32. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
  33. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Quick correction on the specs of the new isometric shader : after testing with half height isometric sprites I've come to realize that there could be a lot more than 3 tile types per "view" tile which means depending on what sprites are being used there could be a need for a few more texture samples. I have a couple ideas on how to optimize this process a bit, one of which would involve specifying "obstructive" tile type relationships which would make it possible to simply avoid adding tile types when they would be completely obstructed by another type rendering in front of them.

    Below you can see an example of this. The left image shows the correct behavior while the right image shows what happens when 4 tile types are required on a single point with only 3 available tile maps to place tiles on. As you can see, since the building placement code goes from bottom to top, left to right, extremely cluttered areas on the map often cause the last added building to be missing a piece. In both examples the "C" type has been completely obstructed, which is where the optimization I talked about in the first paragraph would come into play.


    While 4 tile type arrays / textures sent to the shader work for handling this particular case, I believe the amount of tile maps required to handle an isometric tile map could vary wildly depending on the type of sprites being used. Thin and extremely tall sprites would be especially prone to causing this kind of problem. However, after doing a bit of research I've found information on the topic stating that we should be allowed to have up to 16 samplers / textures in simultaneous use with shaders running in Unity, which I believe to be plenty for most isometric tilesets.
     
  34. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    I've updated the Isometric WebGL Demo with a few of the newest features including a tile selector that can be moved between two positions on the Z axis using a toggle to see how the layering works and the ability to generate a new map by pressing the G key. Tile selection works in a very similar manner to the regular square grid one, however as two rectangular grids are overlapping to accomplish the isometric rendering we must also check which one of the two possible tiles is closest to the mouse cursor. Just like the interaction script of the square grid scripts, the isometric interaction script includes both World Point to Tile Map Point and Tile Map Point to World Point functions.
     
  35. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    After having no power since my last post due to widespread outages in my area last night I was finally able to work on the asset a bit more, this time implementing Obstruction Optimization. This feature is an entirely automated process which builds a library of isometric tile type obstruction relationships used to drastically optimize the amount of sprite stamping needed, which can also reduce the amount of texture samples needed to draw isometric maps.

    The process begins by looping through all of the tile types that can be added to the top layer data and checking whether or not they would be completely hidden behind another type if that type were to be added directly in front. Once an obstructive type is found it is added to a HashMap that is then used during the stamping process so that any tile type that would have been added behind another type which completely obstructs them is instead ignored. Since the type was fully hidden this does not break the rendering in any way while allowing the now free grid space to be taken by a non obstructed tile type.


    Initial testing of the feature shows anywhere around 150k useless tile type stampings being avoided on a 1024x2048 sized grid, as you can see above. I've also labeled each building contained within the selected tile by the order in which they were added ( left to right, bottom to top ). Despite 5 different buildings being contained within this single grid tile, which would break the rendering with 4 available slots, the optimization allowed a piece of the fourth one to be ignored allowing the fifth and final building added within this area to be rendered, despite only 4 slots being available.

    One final thing to note is that much like the amount of tile type slots required per grid square, the optimization quality delivered by the feature depends strongly on the style of sprites being used. For instance, sprites that take an entire isometric tile worth of space ( like the cubes and buildings in the previous screenshots ) are going to obstruct other sprites a lot more than a "thin" sprite which only takes part of an isometric tile.
     
    SirStompsalot likes this.
  36. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    I have to say, I am having an absolute blast working with this!
     
    r3eckon likes this.
  37. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Thank you for this and your review! I should hopefully have the new isometric support out by the end of the month!
     
  38. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Quick update on the release for the next version : I will be taking a bit longer than expected. This is due to the fact that while writing the documentation I realized that the workflow behind adding new layered isometric objects was a bit convoluted and decided to try and automate the process as much as possible.

    Let me explain. While the isometric object sprite splitting was already automated, the process of creating and managing the various tile types required for each part was still manual and very time consuming. This first image shows the Tile Type Manager GUI on my original isometric demo type file. It contains not only single / background tiles such as the Transparent, Water and Grass tiles, but also the various parts of multi tile objects. In code, those values had to be initialized as constants in order to then pack them into a holder class which is fed to the function which adds isometric objects to the tile map.


    As you can see, this require a lot of repetitive / redundant types being shown on the GUI. Also, pointing to the various part sprites becomes annoying rather quickly in the editor, requiring a lot of copy and pasting. The process also required more scripting than I would like it to.

    Therefore, the workflow has been drastically simplified and improved. To begin, the Iso Height value of a created tile type is used to offset the next type value added to the list in order to automatically leave "empty" space for the various parts depending on how high the object will go isometrically. Then, the Resource Folder Sprite Path value must point to a folder root instead of a single sprite file. The parts will be loaded from this folder using an automated numbered naming scheme to find the correct parts.


    This new process works seamlessly with the sprite splitter gui, which uses the same naming scheme when outputting sprites to a folder. So all we need to do is point to that folder after exporting the sprite parts into it using the GUI and configuring their import settings correctly. No need for the manual management of 3 x ISO_HEIGHT + 1 tile types per isometric object. Same thing goes in code, we only need 6 constants to refer to our 6 objects.


    The only part that requires any real attention here is that we must make sure to use the same values as set in the GUI, just like the regular square grid tile types, in order for the values to correctly link to your isometric objects. All of the various "part" types are generated by offsetting from this base value and while they do not exist for us to grab individual parts in code, the Texture2DArray sent to the shader will still contain the various part sprites at these generated indices. This might serve as a quick refresher for some but tile type values are indeed directly used as indices in the texture array containing all of the sprites that can be used for rendering using the shader.

    Finally, to add these objects in the map generator code they are accessed from a dictionary which is also automatically built on initialization. Each IsoTypes instance ( a simple class for holding all the part tile types ) has been added to the dictionary using the object's base value as the key, which means the tile types set above are directly used to access the objects and eventually feed it to the function which adds isometric objects to a tile map. The below image shows a simple random roll applying different types of isometric objects depending on the outcome of the rolls, fetching from the IsometricObjectLibrary dictionary using the constant type values created in the TileType class as keys.

    In summary, to add a new isometric object the updated process involves exporting the sprite parts using the splitter GUI to a folder, adding a tile type with the correct Iso Height using the Tile Type Manager GUI and pointing to the sprite containing folder, and finally adding a constant value in the TileType file in order to have a code reference to the object's base tile type value. This is much more simple and less time consuming than the previous process which required the manual creation of at least 4 tile types per isometric object among other repetitive steps.

    Since I'm not sure when I'll be done with documentation and now bug testing of this new process, the new version will probably release a bit later than expected. I believe I should be pushing the update by the end of the week so unless the asset store team are overloaded release should happen during first week of December!
     
    SirStompsalot likes this.
  39. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Here is the last feature I had time to add to the next version. It's a very important helper function used to turn data set / array indices into classic isometric coordinates and vice versa. This can be used in rendering to limit the map within bounds that make it look like a typical isometric map, as can be seen below, as well as for gameplay related tasks such as the handling of AI movement, general game logic or even map generation.


    This particular coordinate style puts the origin ( 0,0 ) tile at the very top, X axis movements go towards the bottom right while Y axis movements go towards the bottom left. In the below screenshot, the debug console shows the converted coordinate compared to the dataset coordinate. While using this coordinate system to set bounds to the map makes it so the data set contains a lot of useless transparent tiles outside of the set bounds, this is only a rendering effect and the coordinate system would still work fine in handling logic or map generation outside those bounds if this rendering effect was turned off.


    I've only had enough time to add one style of isometric coordinates to the conversion function, but I know others exist such as "staggered" and having the origin at the bottom of the tile map. I may implement those other styles in a next version but for now this is good enough and will allow users to work with the map generation code using a comfortable / common coordinate system rather than having to deal directly with indices of the data set. Those indices do not work as one would expect due to the use of interlaced grids to accomplish isometric rendering.
     
  40. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    I'm digging this! I don't know if you're ready for feedback on the changes yet, but I'm really looking forward to having bottom of the map origin; for those that mix unity & Accelerator, I think it'll be confusing for players to go from 0,0 top to 0,0 bottom.

    Regardless, stoked about the changes!
     
    r3eckon likes this.
  41. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Totally open to feedback at any time! I guess since having 0,0 bottom should be simple enough to add having already worked out the opposite style I'll probably do it for next version since you ask for it. Haven't pushed the update for validation just yet so I can safely add stuff in without causing delays. I wasn't sure what style of coordinates people were most likely to use and through the research I did I noticed a lot of guides on isometric coordinate space used top tile as 0,0 so I assumed it was the most common.
     
  42. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    There we go, just added the coordinate style putting the origin tile at the bottom of the converted coordinate space!


    While I was at it I also added a toggle to easily play test out coordinate debugging with the ability to select which coordinate style is used to convert the array indices. The "Classic Isometric Rendering" toggle is used to limit the map to the classical isometric shape shown in the previous post.

     
    SirStompsalot likes this.
  43. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Great news, the newest version of the asset has already been validated and released to the asset store!
     
    SirStompsalot likes this.
  44. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    Super eager to try this out. Will do this weekend!
     
  45. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Today I managed to test out a new 64x32 tile set with the isometric rendering shader, here is a quick demonstration video showing off the tileset which will most likely be included in a future version of the asset!

     
    SirStompsalot likes this.
  46. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Merry Christmas Everyone! Here is an activation voucher for the asset :)

    ASV-F99T-MT3J-UGED-PXTU-9PVV
     
    SirStompsalot likes this.
  47. Zajrus

    Zajrus

    Joined:
    May 20, 2015
    Posts:
    1
    Very interesting asset. Is it possible to integrate it with Tiled Editor (tmx files) or SuperTiled2Unity?
     
  48. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    Hi, while I have not added an in home integration for Tiled map files, the asset is definitely compatible with the format and a simple API such as TiledSharp would be plenty to parse data arrays from the map file and allow you to then send that data to the rendering shader. You'll need to manually set up everything else including tile types, sprites, etc. according to my documentation but you should be able to effortlessly parse map data and use it with the shader.
     
    SirStompsalot likes this.
  49. r3eckon

    r3eckon

    Joined:
    Jul 3, 2015
    Posts:
    506
    After getting a few questions regarding map files I've recently added a way to save and load tile maps using hard drive stored files. Since the isometric tile map using "classic rendering" relies on lots of empty space to achieve the classic look, it can benefit greatly from simple run length encoding of the empty space in order to compress the map file, as you can see below!


    While the total size of the map array is actually 4100x8192 as shown in the next image, the final picture linked in this post shows the true size of the "classic isometric" style map area for the above map files as being 2048x2048.



    Square tile maps of a same size would most likely create map files of smaller size due to the inherently multi layered nature of the isometric maps. While I feel like this file size is pretty good considering how wide of a play area it creates, depending on the amount of tile types being used and the noisiness of the tile map data run length encoding could be used to further reduce file size.
     
    Last edited: Jan 6, 2020
  50. SirStompsalot

    SirStompsalot

    Joined:
    Sep 28, 2013
    Posts:
    112
    Run length encoding is definitely a good idea! :D
     
    r3eckon likes this.