godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.48k stars 21.26k forks source link

Mipmaps Limit import setting is not respected #63934

Open allenwp opened 2 years ago

allenwp commented 2 years ago

Godot version

v4.0.alpha13.official [59dcddc45]

System information

Windows 10, Vulkan Mobile, NVIDA 980 Ti

Issue description

The Mipmaps Limit setting in the Texture2D import settings is not respected.

mipmaps-limit-bug

(In the above screenshot, note that the Limit is set to 5, but there are 13 mipmaps for this Texture2D resource.)

Steps to reproduce

  1. Add a new Texture2D resource to the FileSystem.
  2. Select the new texture resource and view the Import panel
  3. Turn on Generate under Mipmaps
  4. Click "Reimport" button
  5. Set the Limit to something other than -1
  6. Click the "Reimport" button again
  7. Select the Texture2D resource in the FileSystem to view it in the Inspector panel
  8. Note that the inspector shows that there are more mipmaps in the Texture2D resource than in the Limit setting

Minimal reproduction project

MipmapsLimitBug.zip

Chaosus commented 2 years ago

Does it reproducible in 3.5?

allenwp commented 2 years ago

Does it reproducible in 3.5?

The "Limit" setting does not exist in v3.5.stable.official [991bb6ac7], so this bug is specific to 4.0.

allenwp commented 2 years ago

From looking at the source code, it appears that this Limit setting is not yet used by the Image class when mipmaps are generated. In ResourceImporterTexture::_save_ctex, the setting is saved to the CTEX file: f->store_32(p_limit_mipmap);, but then is never passed on to the Image for it to be used by its Image::generate_mipmaps function.

Further to this, Image::_get_dst_image_size seems to just count to the max possible mipmaps without using the Limit setting.

From looking at the git log, it seems the setting was originally introduced by reduz in 6deffa62fbd1e91873afa663630b788b9ffabee3 and 4aea9f74e650743fe6585d5230dd6e5f6c94c478 of Sept 2019.

(I don't personally have a use for this setting and I think it'd be fine to just hide the GUI for it and revisit this in a later 4.x release, unless someone already has the implementation of this feature in a PR somewhere...)

Calinou commented 1 year ago

I can still reproduce this on 4.0.2.

vfig commented 10 months ago

this bit me today, in 4.1.3.

i was rendering grass blades, and having issues with a whitish fringe appearing when the blades were at a steep angle to the camera, or the blades turning entirely to white further from the camera. grassbug grassbug2

the grass is being rendered with the texture below. using renderdoc, i concluded the issue was due to the 7th (1x1) mip being used, as by then the texture is reduced to a single whitish-green pixel (shown scaled up here so it is visible). grass_mip0 grass_mip7_zoomed

i tried to use the Mipmaps Limit setting on the .tga's import settings and reimporting, and found it was having no effect at all. this misled me into thinking the fringing problem was something other than mips, but after some time i eventually changed the shader to manually specify the lod to sample, to confirm that yes, it was actually this mip being the problem, and that for some reason the Mipmaps Limit setting was not working.

for a workaround, i suppose i can either generate a .dds elsewhere without this last mip, or query and clamp the mip levels in the fragment shader.

NuclearPhoenixx commented 5 months ago

I ran into a problem today where textured terrain in the distance looked quite weird and distorted due to mipmaps (nearest mipmap filter on the texture). My best guess is this is caused by the last one or two mipmaps that get generated on my pixel art texture leading to a miscoloring of terrain.

Anyways, I don't want to got into too much detail here, it would be extremely helpful to limit the number of mipmaps so I support this issue. Is there any other way to maybe don't generate the last mipmap or so?

Calinou commented 5 months ago

Is there any other way to maybe don't generate the last mipmap or so?

Yes, using a DDS texture that comes with custom mipmaps already present in the file. Many programs like GIMP can write DDS textures with custom mipmaps (one mipmap in each layer).

Calinou commented 5 months ago

I've started looking at fixing this issue, but I couldn't get it to work yet as uninitialized data is present in the smaller mipmaps once you turn on the limit: https://github.com/Calinou/godot/tree/image-fix-mipmaps-limit-import-option

This means that seemingly random pixels appear in the distance every time you reimport. Any ideas?

Testing project: test_rgss.zip

image