Expanding on Tile Textures

Discuss modding questions and implementation details.
User avatar
King of Worms
Posts: 3945
Joined: Mon Oct 17, 2016 11:18 pm
Location: Scourg Barrow (CZ)
Contact:

Re: Expanding on Tile Textures

Post by King of Worms »

Daniel87 wrote: Sat Apr 24, 2021 7:04 pm
Hazelnut wrote: Sat Apr 24, 2021 2:47 pm That would be me and Interkarma.

Is there a specific question?

Each tile is a byte that's used by the shader. 2 bits are used for rotation & flip leaving 6 bits, so theoretically 8 more tiles could be added however that could cause issues with the city outskirts which use those values. I think you had researched that Burt IIRC. Also FF is needed to represent 0 so the terrain and location tiles don't conflict.
At my mod, I hit a road block related to the tile set of the original daggerfall. Basically my question would be:
- Do you know if it is possible to append additional tiles for terrain transitions to the existing original tile sets of Daggerfall? and
- Is there a way of unpacking these tile set files of original DF, adding new tiles and repacking them or would placing additional textures in StreamingAssets/Textures be easier to implement?

General fact: I can only rotate tiles by 180° (the so-called "Flip"-Bit that only rotates) and by 90°(Rotate-Bit) but I cannot mirror them, which is required in about 50% of terrain transitions. Since they cannot be flipped horizontally or vertically, it will look like in the image below.

Image

These are the tiles which I would need to mirror in Photoshop and add into the original tile set or append in another way. Flipping them by code might also solve the problem partially but then still there would be some terrain transitions missing, which were never included in the original DF, see below.

Image

The tiles with red frame:
These tiles would need a mirrored version. Usually, they consist of 2x the same and 1x a second tile + 1x third tile, by example (dirt, dirt, water, stone). I would need a version with (dirt, dirt, stone, water) where they are simply flipped on one axis.

The tiles with green frame:
From these tiles I would need a version, where there is a third texture included.
by example we have (dirt, water, dirt, water) in the four corners. What I would need to add to the atlas is (dirt, water, dirt, stone) and (dirt, water, dirt, grass) etc.
I think all permutations possible would be:
Dirt: (dirt, water, dirt, stone) , (dirt, water, dirt, grass), (dirt, stone, dirt, grass)
Water: (water, dirt, water, grass), (water, dirt, water, stone), (water, stone, water, grass)
Stone: (stone, dirt, stone, grass), (stone, water, stone, grass), (stone, dirt, stone, water)
Grass: (grass, dirt, grass, water), (grass, dirt, grass, stone), (grass, water, grass, stone)

Then there is also a couple of versions with all 4 tile types joining that also is not in the standard tile set:
(water, dirt, stone, grass), (water, stone, dirt, grass), (water, grass, stone, dirt), (water, grass, dirt, stone)

I am not sure if that will be all possible permutations needed, but we could still extend on that, if it is basically possible to add more than X tiles per set.

I hope I could explain what I am planning to do and where I am failing.
Currently I hardcoded all possible terrain transitions, also the ones that were not possible before (water -> grass) or (water -> stone) and are only used in locations.
I can provide - when the feature is implemented - the flipped ones for the vanilla and dream. I can also provide all dream tiles for anyone who is bold enough to create the missing tiles described above (not the flipped ones but the ones which need to be created a new - green ones)

User avatar
TheLacus
Posts: 1332
Joined: Wed Sep 14, 2016 6:22 pm
Contact:

Re: Expanding on Tile Textures

Post by TheLacus »

I have an open PR that will allow to override material assignment to terrain. For example you can extend TilemapTerrainMaterialProvider and use default shader but with your custom tile atlas instead of what is created by MaterialReader; individual textures can be imported with TextureReader or TextureReplacement. You can also use a custom shader, if needed.
BadLuckBurt wrote: Sat Apr 24, 2021 7:12 am Under DaggerfallTools in Unity, there's also the Texture Array Creator, don't know how it works exactly but others probably do.
It can be used to create a Texture2DArray and store it as an editor asset, which might or might not be useful depending on which shader is used.
Mod System documentation - Learn how to create mods for Daggerfall Unity.
Modder Discussion - General help and discussion for the mod system.
Github Issues - Submit a bug report for the game, including the mod system.

User avatar
Daniel87
Posts: 245
Joined: Thu Nov 28, 2019 6:25 pm

Re: Expanding on Tile Textures

Post by Daniel87 »

TheLacus wrote: Sat Apr 24, 2021 7:27 pm I have an open PR that will allow to override material assignment to terrain. For example you can extend TilemapTerrainMaterialProvider and use default shader but with your custom tile atlas instead of what is created by MaterialReader; individual textures can be imported with TextureReader or TextureReplacement. You can also use a custom shader, if needed.
BadLuckBurt wrote: Sat Apr 24, 2021 7:12 am Under DaggerfallTools in Unity, there's also the Texture Array Creator, don't know how it works exactly but others probably do.
It can be used to create a Texture2DArray and store it as an editor asset, which might or might not be useful depending on which shader is used.
I will go with the original textures/shaders used by DF.
The idea was just to complement the existing terrain texture atlas, append additional tile transition textures that are missing and hardcode the Lookup Table for the marching square algorithm in TerrainTexturing.cs to implement all tile texture transitions where necessary on the terrain.

That PR was really freakin awesome! Simply amazing! Thank you so much!
You are a wizard conjuring functions, classes and such out of thin air just like this in such a short time! <3

How would I go about using these functions/the new ITerrainMaterialProvider, once the PR is through? I mean explained for dummies like me:
- What would be the basic procedure to add an additional tile to an existing terrain tile set like TEXTURES.302?

I was trying to find that DFU Tool "Texture Array Creator" but couldn't find it on the dfworkshop. All I found in google was this:
https://gist.github.com/TheLacus/5b96d8 ... dff8c8daba but its a 404.

Sorry for the stupid questions, it's my first time using the functions and processes you mentioned and working with shaders/materials/textures in this context.

Theoretically that also opens the door for me to create fluid climate zone transitions as well, no? So exciting!

User avatar
TheLacus
Posts: 1332
Joined: Wed Sep 14, 2016 6:22 pm
Contact:

Re: Expanding on Tile Textures

Post by TheLacus »

Hi,

The new ITerrainMaterialProvider is intended to be used to effectively implement terrain tilemap provided by ITerrainTexturing; I originally needed it for my splat map mod, but i tought it was worth to mention it as it might be useful for your purpose. I don't know how feasible is to add new kind of tiles without giving it a deeper look, but, if useful, i can say that there are two shaders used by the core game: Tilemap (which uses an atlas) and TilemapTextureArray (which uses a texture array). In both cases the generated tilemap is used by the shader with provided textures (see PromoteMaterial). That would be the place to make use of tile data as needed, for example to inject a modified version of tilemap shader.

You can place individual textures in StreamingAssets/Textures or bundle them in your mod, then make an atlas or texture array at runtime. Texture Array Creator is part of the tools available inside the Unity Editor if you open Daggerfall Unity repository, in the same place where Mod Builder can be found, and can be used to make a texture array directly in editor. But i don't think this is the most important part now, i'd suggest to investigate how tilemap and shader work first.

I think climate transitions might be possible with a custom shader, but i assume that would require a single terrain to hold textures for all climates involved with potential performance implications.
Mod System documentation - Learn how to create mods for Daggerfall Unity.
Modder Discussion - General help and discussion for the mod system.
Github Issues - Submit a bug report for the game, including the mod system.

User avatar
Daniel87
Posts: 245
Joined: Thu Nov 28, 2019 6:25 pm

Re: Expanding on Tile Textures

Post by Daniel87 »

TheLacus wrote: Sat Apr 24, 2021 10:27 pm Hi,

The new ITerrainMaterialProvider is intended to be used to effectively implement terrain tilemap provided by ITerrainTexturing; I originally needed it for my splat map mod, but i tought it was worth to mention it as it might be useful for your purpose. I don't know how feasible is to add new kind of tiles without giving it a deeper look, but, if useful, i can say that there are two shaders used by the core game: Tilemap (which uses an atlas) and TilemapTextureArray (which uses a texture array). In both cases the generated tilemap is used by the shader with provided textures (see PromoteMaterial). That would be the place to make use of tile data as needed, for example to inject a modified version of tilemap shader.

You can place individual textures in StreamingAssets/Textures or bundle them in your mod, then make an atlas or texture array at runtime. Texture Array Creator is part of the tools available inside the Unity Editor if you open Daggerfall Unity repository, in the same place where Mod Builder can be found, and can be used to make a texture array directly in editor. But i don't think this is the most important part now, i'd suggest to investigate how tilemap and shader work first.

I think climate transitions might be possible with a custom shader, but i assume that would require a single terrain to hold textures for all climates involved with potential performance implications.
Oof, okay I will give it a shot tomorrow.
It seems as if the MaterialReader does not really support atlases > index of 55, won't this cause problems when I try to create my own atlas at runtime or is this only an issue when loading files from the HDD?

EDIT: Okay, I think I misunderstood. Inside of ITerrainMaterialProvider rather than using MaterialReader.GetTerrainTextureArrayMaterial() I should create my own Terrain Texture Array from lose files in StreamingAssets/Textures and build the Material with those instead, right?

User avatar
Daniel87
Posts: 245
Joined: Thu Nov 28, 2019 6:25 pm

Re: Expanding on Tile Textures

Post by Daniel87 »

Smoll update:
TheLacus wrote: Sat Apr 24, 2021 10:27 pm
I was able to implement your PR into my DFU, change the Shader, created a TextureArray with additional tiles (68 currently but in the future more likely around 80-90 different tiles) and loaded them via my mod into the game.

Tile rotation and flipping is completely off, as it is adding +64 and +128 (changing the two left most bits) to the index of the tileMap array, which is of type byte[].
Since DaggerfallTerrain is working with this limiting byte structure and currently not modable, it seems to be impossible to add more than 64 textures to a texture array. :cry:

This code part seems to be the culprit.

You suggested to inject my additional tiles at PromoteMaterial(), which I did, but then still flip and rotation bits pose a problem, as these two bits limit my terrain index to 64 tiles and DaggerfallTerrain receives this byte for each tile, stores it in tileMap and feeds this together with other information back into PromoteMaterial(). So if I try and create a lookup Table with more than 64 different tiles, the rotation bit will get lost and having 128 tiles will also purge the flip-bit.

My only idea right now is to rather encode the tile type of all 4 neighbours of a tile in the tileMap byte. Ignoring roads, there are 4 possible tile types: water, dirt, grass and stone.
a tileMap byte has 8 bits, so I can encode the numbers from 0 - 3 in 4x2 Bit. So a tile with the neighbours (dirt, water, water, grass) would be "01000010"
This way, I will need to adapt the Shader, so it stops filling the material with rotated versions of the same tile and I need to manually add all rotated variations of each tile texture to the Texture2DArray. This will be 4x as memory intense, but I cannot think of any other solution currently. Please let me know if you have any other idea.

(I also don't really like, that this means roads and farmland as well as compatibility with basic roads will never be possible)

EDIT:
Nevermind, I deleted all unused textures (specks of dirt/water/stone surrounded by another texture) and restricted the terrain layout to have only dirt border water, which allowed me to remove another couple of textures. Now the transitions between dirt/stone and grass work perfectly. Will have to change the textures a little bit, as they still look a little odd, but yeah, the texturing of terrains is now enhanced and allows for more variety.

Image

User avatar
King of Worms
Posts: 3945
Joined: Mon Oct 17, 2016 11:18 pm
Location: Scourg Barrow (CZ)
Contact:

Re: Expanding on Tile Textures

Post by King of Worms »

Sounds great, just be double-sure the unused assets are really unused.
When u said "specks of dirt/water/stone surrounded by another texture" It immediately reminded me this screen I took back than...

Spoiler!
01.jpg
01.jpg (489.17 KiB) Viewed 82 times

User avatar
Daniel87
Posts: 245
Joined: Thu Nov 28, 2019 6:25 pm

Re: Expanding on Tile Textures

Post by Daniel87 »

Urgh! Don't scare me. Let me just check if towns and cities are okay.

EDIT: How could I be so stupid?! Locations are totally messed. Let's hope I find a way to swap between the TerrainTexturing scripts when creating locations and terrains. Otherwise all the work was for nothing >_<

Image

Gosh, what a PAIN! I start really hating this stupid Byte terrain system that caused me nothing but problems from the start.

EDIT2: Okay, I conjured some of my magical spaghetti code and made a quick n dirty fix for the problem.
I am by no means happy with this, but compared to basic DF, it's still an overall improvement I guess.

I now texture terrains w/o location via my own texture sets, while treating terrains with location via the standard TerrainTexturing and standard texture sets.
It slightly convolutes my already overly-convoluted code, but whatever.

On the picture you can see, that there are still cases, where the transitions look crappy on terrains with location, but we will have to accept this until I find a way to use two different materials on the same terrain.

I was thinking of maybe re-evaluating the exact tiles that hold a location and applying a different texture to them in the middle of texturing the terrain, but this will most likely be a real performance killer - holding two materials for each climate and season all the time and switching between them while looping through all terrain tiles... these limitations sometimes are really hard to bear. I will put this on the very end of my ToDo list...

Image
Last edited by Daniel87 on Mon Apr 26, 2021 10:53 pm, edited 1 time in total.

User avatar
Hazelnut
Posts: 2693
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Expanding on Tile Textures

Post by Hazelnut »

Daniel87 wrote: Sun Apr 25, 2021 6:56 pm
Tile rotation and flipping is completely off, as it is adding +64 and +128 (changing the two left most bits) to the index of the tileMap array, which is of type byte[].
Since DaggerfallTerrain is working with this limiting byte structure and currently not modable, it seems to be impossible to add more than 64 textures to a texture array. :cry:

This code part seems to be the culprit.
I did explain that you would only be able to reference 64 max (well probably only 62 with the city boundary value and the FF swapped with 0) due to the rotation and flip bits. This is how the daggerfall terrain system works, and that's what DFU replicates.

Not sure what you mean about that code, I wrote that so I'd like to understand what you think it's the culprit for?


Unfortunately I've got a massive amount of stuff going on right now so I've only skim read the thread and I've not been able to really understand what your issue with the rotation and flip bits are... my recollection is that they allow all orientations of the available tiles. I did become aware that there are some transitions missing from the terrain texture set. I didn't think it was so many that finding a mechanism to allow for an extra 8 wouldn't be enough. That should be doable through the existing 1 byte per tile system.

If more is required then that will need more than just replacing the TerrainTexuring which is setup to provide a byte array which is compatible with the DFU terrain shader.
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

User avatar
Daniel87
Posts: 245
Joined: Thu Nov 28, 2019 6:25 pm

Re: Expanding on Tile Textures

Post by Daniel87 »

Hazelnut wrote: Mon Apr 26, 2021 9:24 pm
Daniel87 wrote: Sun Apr 25, 2021 6:56 pm
Tile rotation and flipping is completely off, as it is adding +64 and +128 (changing the two left most bits) to the index of the tileMap array, which is of type byte[].
Since DaggerfallTerrain is working with this limiting byte structure and currently not modable, it seems to be impossible to add more than 64 textures to a texture array. :cry:

This code part seems to be the culprit.
I did explain that you would only be able to reference 64 max (well probably only 62 with the city boundary value and the FF swapped with 0) due to the rotation and flip bits. This is how the daggerfall terrain system works, and that's what DFU replicates.

Not sure what you mean about that code, I wrote that so I'd like to understand what you think it's the culprit for?


Unfortunately I've got a massive amount of stuff going on right now so I've only skim read the thread and I've not been able to really understand what your issue with the rotation and flip bits are... my recollection is that they allow all orientations of the available tiles. I did become aware that there are some transitions missing from the terrain texture set. I didn't think it was so many that finding a mechanism to allow for an extra 8 wouldn't be enough. That should be doable through the existing 1 byte per tile system.

If more is required then that will need more than just replacing the TerrainTexuring which is setup to provide a byte array which is compatible with the DFU terrain shader.
The problem with the rotation and flip bit is that the flip actually just rotates by 180° instead of mirroring the texture, so I created my own Texture2DArray with mirrored versions (see picture).
Image
By culprit I meant that that function in DaggerfallTerrain is using the Byte format for textures, which forces me inside of TerrainTexturing to use that format as well hence limiting me to 64(62) tile textures. (At that point when I wrote it, I was trying to find a way of circumventing the whole "texture as a byte"-system because of its limitations. So far I found a "quick n dirty" workaround and will come back to it at a later point.
So what I want to say is, nothing wrong with your code, no worries. It's just limiting my options for my mod, but I think I didn't try all possibilities yet to solve the problem, so there is currently no need to change anything about the DFU code.

Post Reply