Zylann / godot_heightmap_plugin

HeightMap terrain for Godot implemented in GDScript
Other
1.73k stars 159 forks source link

Texture sets #212

Open Zylann opened 3 years ago

Zylann commented 3 years ago

This is an upcoming feature I'd like to expose before I merge it. Texture sets would be a new custom resource to setup terrain textures, replacing the old way.

Existing system

So far setting up textures for the ground was up to the user, as explained here: https://github.com/Zylann/godot_heightmap_plugin/blob/master/addons/zylann.hterrain/doc/main.md#texturing

If you used a classic shader, you had to make 4 pairs of textures that are each packed like this:

You had to do this packing yourself in an image editor, or using a separate plugin.

If you used an array-based shader, you had to not only do that, but also assemble all your textures in an atlas, and use the default TextureArray importer of Godot, which is impractical and time consuming (also you better have lots of RAM to spare).

Proposal

HTerrainTextureSet will be a new resource that can hold a collection of terrain textures. It lets you define source images (albedo, bump, normal, roughness), and allows to import them into the kind of texture the plugin expects. This way, you won't need to use an external tool anymore, and changing one of the source images is a lot simpler in the case of texture arrays.

Each HTerrain node will start with one of these resources by default, and once you choose the data directory, it will be saved next to the data.hterrain resource, as a simple .tres file. The generated textures will then be saved in the same place, either as .stex or .texarr. In this workflow, source images may not be used by the game, so it will be possible to place them in a folder with a .gdignore file, so they won't bloat the exported build. This leads to the following folder organization:

terrain_test/

    source_textures/
        .gdignore
        grass col.png
        grass nrm.png
        grass rgh.png
        grass bmp.png
        Rocks_Albedo.jpg
        Rocks_Bump.jpg
        Rocks_Normal.jpg
        Rocks_Roughness.jpg
        ...

    terrain_data/
        color.png
        data.hterrain
        detail.png
        detail2.png
        global_albedo.png
        height.res
        normal.png
        splat.png

        textures.tres <-- TEXTURE SET
        textures_t0_albedo_bump.stex <-- IMPORTED TEXTURES
        textures_t1_albedo_bump.stex
        ...
        textures_t0_normal_roughness.stex
        textures_t1_normal_roughness.stex
        ...

    terrain_test.tscn

Note: because it behaves like a regular resource, it is also possible to re-use the same pre-made set of textures for multiple terrains, by assigning it in the inspector.

Interface

There will be a custom interface to configure a HTerrainTextureSet, which can be shown either by inspecting the .tres resource, or with a shortcut from the terrain editor (double-click on any texture slot, or choose Edit...).

Work-in-progress: image

Other options may also include default values for non-filled slots, normalmap strength to allow using DX convention from CC0Textures, and a mode to switch between texture arrays and individual textures, depending on the shader you are using.

RonanZe commented 3 years ago

Seems to be a nice workflow improvement. What are the drawbacks?

Zylann commented 3 years ago

@RonanZe if you only want to use albedo textures without normals, without fancy blending, and only 4 textures, then you might find the process a bit redundant compared to assigning textures directly without import step (although Godot still imports from PNGs to STEXs in any case).

Zylann commented 3 years ago

I was in the testing phase when I found the following blockers. I was hoping that I would be able to generate StreamTextures or TextureArray from code, save them, assign them to the TextureSet resource, and finally save it. Simple? NOPE:

The alternative is to not import, and just generate PNGs, then reverse-engineer .import files. It's also dirty, but not as bad, and I did this already with terrain data. Downside is:

Conclusion:

I wasted two nights on this so I'll make a pause there... I need to figure out what to do from here, because it appears what I wanted to do is impossible, not with extra steps from the user (crazy, right)... I would really like to get the design from my previous post though... the "correct" way Godot is exposing feels very limiting.

Zylann commented 3 years ago

Update: I've been working hard to overcome some of the issues I had earlier, and I managed to get this feature working in the end, with a few differences from the initial proposal.

The feature is available to test in the texture_sets branch, along with new documentation https://github.com/Zylann/godot_heightmap_plugin/blob/texture_sets/addons/zylann.hterrain/doc/main.md#texturing

Zylann commented 3 years ago

This is now in master.