godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Add to texture import settings "Pixel Format" option #2107

Open Summersay415 opened 3 years ago

Summersay415 commented 3 years ago

Describe the project you are working on

Any

Describe the problem or limitation you are having in your project

When I am importing textures I can't select pixel format(e.g. "L8, L8A8, RGB24, RGBA32, RGBA4444, RGBA5551, DXT1-DXT5")

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add to texture import settings "Pixel Format" option with values "L8, L8A8, RGB24, RGBA32, RGBA4444, RGBA5551, DXT1-DXT5" and add correspond import.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Add to texture import settings "Pixel Format" option with values "L8, L8A8, RGB24, RGBA32, RGBA4444, RGBA5551, DXT1-DXT5" and add correspond import.

If this enhancement will not be used often, can it be worked around with a few lines of script?

This is import function and cannot be realized with script.

Is there a reason why this should be core and not an add-on in the asset library?

This is import function.

Calinou commented 3 years ago

The pixel format is chosen automatically based on the input texture. In the interest of simplicity and ease of use, there never was a way to force it in the Import dock and I doubt this will change.

SIsilicon commented 3 years ago

Then can't that just be an "advanced" option? This can actually be useful for when you have textures that store data that an RGB(A) wouldn't need to. For example, a grey scale image only needs red channel.

Calinou commented 3 years ago

This can actually be useful for when you have textures that store data that an RGB(A) wouldn't need to.

In this case, it's better to remove the alpha channel from your original texture to save storage space. There are many tools to do this such as oxipng.

Also, until https://github.com/godotengine/godot-proposals/issues/2041 is implemented, we can't really have "advanced" import options to speak of.

SIsilicon commented 3 years ago

Alpha isn't the only channel that might not need to be omitted. Like I said, a grey scale only needs one channel, and yet can only be imported in 3.

Zylann commented 3 years ago

This is import function and cannot be realized with script.

It can, but it's extremely tedious https://github.com/godotengine/godot-proposals/issues/1943

Calinou commented 2 years ago

Alpha isn't the only channel that might not need to be omitted. Like I said, a grey scale only needs one channel, and yet can only be imported in 3.

I double-checked and this used to be correct until Godot 3.4, but not since Godot 3.4. The reason is that since Godot 3.4, lossless WebP is used instead of PNG to provide smaller file sizes for lossless-compressed files. However, we don't make use of WebP's grayscale formats to reduce memory usage (or at least perform a load-time format conversion when possible). This can be worked around by enabling Force Png in the Project Settings, selecting all your textures in the Import dock then clicking Reimport. Double-click them and you should see the correct format appear in the inspector preview.

I've tested dozens of formats with all compression modes on master 1032c2c43, and here are my findings with the default project settings (= lossless WebP is used):

Testing project (master): test_image_formats.zip

Included file types in each folder:

test_indexed_alpha.png:        PNG image data, 256 x 256, 8-bit colormap, non-interlaced
test_indexed.png:              PNG image data, 256 x 256, 8-bit colormap, non-interlaced
test_l8.png:                   PNG image data, 256 x 256, 8-bit grayscale, non-interlaced
test_la8.png:                  PNG image data, 256 x 256, 8-bit gray+alpha, non-interlaced
test_rgb8.png:                 PNG image data, 256 x 256, 8-bit/color RGB, non-interlaced
test_rgba8.png:                PNG image data, 256 x 256, 8-bit/color RGBA, non-interlaced
test_l8.jpg:                   JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, comment: "Created with GIMP", progressive, precision 8, 256x256, components 1
test_rgb8.jpg:                 JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, comment: "Created with GIMP", progressive, precision 8, 256x256, components 3
test_webp_lossless_l8.webp:    RIFF (little-endian) data, Web/P image
test_webp_lossless_la8.webp:   RIFF (little-endian) data, Web/P image
test_webp_lossless_rgb8.webp:  RIFF (little-endian) data, Web/P image
test_webp_lossless_rgba8.webp: RIFF (little-endian) data, Web/P image
test_webp_lossy_l8.webp:       RIFF (little-endian) data, Web/P image
test_webp_lossy_la8.webp:      RIFF (little-endian) data, Web/P image
test_webp_lossy_rgb8.webp:     RIFF (little-endian) data, Web/P image
test_webp_lossy_rgba8.webp:    RIFF (little-endian) data, Web/P image
test_l8.tga:                   Targa image data - Mono 256 x 256 x 8
test_rgb8.tga:                 Targa image data - RGB 256 x 256 x 24
test_rgba8.tga:                Targa image data - RGBA 256 x 256 x 32 - 8-bit alpha
test_l8.bmp:                   PC bitmap, Windows 98/2000 and newer format, 256 x 256 x 8
test_rgb8.bmp:                 PC bitmap, Windows 98/2000 and newer format, 256 x 256 x 24
test_rgba8.bmp:                PC bitmap, Windows 98/2000 and newer format, 256 x 256 x 32
viktor-ferenczi commented 2 years ago

I have this same problem while trying to load images into a Texture2DArray, where all layers must have the exact same format. Layer 0 needs to be full black, but the automatic import screws it by forcing DXT1 RGB8 instead of DXT5 RGBA8 the other layers have. It results in an "All images must share the same format" error at runtime. I'm aware it may be worked around, but why to work on that if the setup could be very simple by manual format selection?

Zylann commented 2 years ago

How is texture import related to loading Images into a Texture2DArray? An Image is not a texture, and can be loaded with the Image.load function. You won't have any issue with them being compressed that way. Are you hitting this issue because you did load("some_texture.png").get_data()? If you did, you should likely not load the images this way I guess (that code first loads the texture in RAM, then uploads it into graphics card memory, and then downloads it back to RAM in its format , which was likely compressed and optimized, which is why you'd hit such an issue with different formats).

viktor-ferenczi commented 2 years ago

You are right, I mess up something in code for sure. Just working on fixing it. But still, being able to explicitly specify an import format would still be nice.