Zylann / godot_heightmap_plugin

HeightMap terrain for Godot implemented in GDScript
Other
1.67k stars 156 forks source link

Imported Maps are blurred? #402

Open Igameart opened 9 months ago

Igameart commented 9 months ago

My imported maps appear to be gaussian blurred after loading into HTerrain, both the heightmap and the splatmap.

Here is a terrain in blender: image

This is the same terrain in Godot after importing the exported height and splatmaps: image

A portion of the splatmap: image

I am using Godot 4.1.1 Using the version of HTerrain found in the AssetLib as of this week, Windows 11 RTX 3050 Forward+ renderer.

Zylann commented 9 months ago

Assuming resolution hasn't changed between Blender and Godot, I don't know what's up here. The plugin doesn't do any blurring. The only "blurring" is the normal linear interpolation done by the shader when it reads the textures, and yet for the heightmap sampling happens at pixel centers. Eventually there will be some degree of pixel conversion depending on the format you exported the textures with. The heightmap looks fine, outside very minor differences.

There will be some differences because it's very likely the way it is rendered in Blender and Godot differs. Shaders have different options. The plugin also uses a geometry pattern that's likely different than the one you used in Blender (check wireframe).

Which shader are you using? Which resolution are your heightmap and splatmap when exported from Blender? Do you have a test project I can reproduce this issue in, with the original heightmap and splatmap to import and compare? (btw your splatmap has a lot of yellow in it, means there are areas where two textures from R and G will show at 50%/50% opacity at the same time; I also assume you omitted the alpha channel when you posted it?). I can't really tell what is happening here. You can try checking the splatmap in lookdev mode, or tinker with the terrain shader maybe...

lorddevereux commented 9 months ago

I have been battling with understand this sort of problem - and so I offer the following observations in case they help. Part of this I think is due to weird or niggly differences in Godot 4 so the documentation needs a bit of adjustment.

I'm using

Maybe some of these things are obvious to people used to game dev, but they weren't to me!

I now have my data set mostly working properly. The lack of trilinear blending in Multisplat16 (seems to also be a documented limit of Texture2DArray in Godot 4) makes the tiling a bit blocky, but I think I can get around that by increasing the splatmap resolution and applying a slight blur to smooth harsh texture changes.

Screenshot from 2023-10-07 20-52-54

Looking at the OP issue, is it possible that the shader is simply applying a "smooth" kind of normal shading rather than "flat", therefore rounding off the heightmap peaks?

Zylann commented 9 months ago

About splatmaps:

If you're using multisplat, importing splatmaps is going to be a bit different, I'm not even sure the plugin has an option to import more than one splatmap. How did you import them in? I guess you can do so by doing what you described, normalizing all weights across all splatmaps and save them as PNGs over those generated by the plugin in your terrain directory. Some extra things to consider:

About ground textures:

The lack of trilinear blending in Multisplat16 (seems to also be a documented limit of Texture2DArray in Godot 4) makes the tiling a bit blocky,

I'm not aware of such a limitation. Where did you see this? The plugin's shader does use linear filtering when sampling texture arrays. What the doc might say is that filtering will not work when sampling across two different layers of the array (Z axis), which is normal and isn't a problem for terrain rendering. Filtering should work fine on XY axis (since textures are 2D). Also the fact you enabled VRAM-compression on these might make them look a bit blocky too, but that's usually not noticeable.

About the heightmap:

Looking at the OP issue, is it possible that the shader is simply applying a "smooth" kind of normal shading rather than "flat", therefore rounding off the heightmap peaks?

The heightmap sampler uses default bilinear filtering, however it samples it the middle of each pixel: https://github.com/Zylann/godot_heightmap_plugin/blob/222b4abd81213bab3d93d831a2bd4d75a530d3fc/addons/zylann.hterrain/shaders/multisplat16_lite.gdshader#L162 Therefore it does not smooth anything when it comes to vertex displacement. You could try changing it to do no filtering at all by replacing the heightmap uniform with uniform sampler2D u_terrain_heightmap : filter_nearest;, but I doubt it will change anything.

Some possible causes that come to mind:

lorddevereux commented 9 months ago

For the splatmaps - I imported the first one which created splat.png, then I copied the others to splat2, splat3, splat4.png and it works perfectly.

Make sure that splatmaps are NOT VRAM-compressed,

Thank you, that fixed it! I suppose I assumed that because the texture map was VRAM compressed, the splatmaps should be as well. I think that was the default though, but perhaps Godot set it like that because I added them to the project manually.

Screenshot from 2023-10-07 23-40-12

I'm using Python/Pillow to generate all the images here (from binary datasets) and that does (correctly) preserve all channels when in RGBA mode.

I'm not aware of such a limitation. Where did you see this? According to this: https://docs.godotengine.org/en/stable/classes/class_texture2darray.html#class-texture2darray. The statement was not present in the Godot 3 documentation on TextureArray. However, you may be right, it might only be Z axis.

Sorry for slightly hijacking the post. I'm happy to share the Python code I used to normalise the splatmaps if that's helpful. Thanks again.