godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.17k stars 98 forks source link

Allow textures to be stored in grayscale #5182

Open josefkaragoli opened 2 years ago

josefkaragoli commented 2 years ago

Describe the project you are working on

A 3D semi-open world 3D game with lots of textures and assets

Describe the problem or limitation you are having in your project

While optimizing, it is necessary to cut down on textures using a lot of VRAM, by removing redundant data or optimizing textures which have little influence on the final look. I've found that when working with PBR textures, many grayscale textures used in the process, like roughness, metalness, AO and height do not need to be RGB. By being RGB they take up significantly more memory than needed, and this is especially true for large (2k, 4k, 8k) textures with these redundant channels. While it is possible to combine them into an ORM map, this method is not ideal for several reasons:

That said, I still see the use in using packed textures, especially considering the fewer texture lookups needed. I just think it is simpler and more conducive to a non-destructive workflow to be able to store grayscale-only textures.

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

While importing a Texture2D, a new import flag should be added, allowing users to specify whether to make the texture grayscale. By default it should be disabled obviously, so as to not create confusion - this should only be a user-specified setting in the optimization phase.

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

image

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

It concerns the way Godot compresses imported textures, and I don't think this is exposed to the user.

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

This should be exposed to the user by default.

Calinou commented 2 years ago

Related to https://github.com/godotengine/godot-proposals/issues/3184.

I think Godot should automatically detect textures and import them with the appropriate format. Most people will not bother manually ticking a Grayscale box on every PBR map texture; we should strive for optimization to happen automatically as much as possible.

For textures using Lossless compression, this happened automatically until Godot 3.3, but was lost with lossless WebP compression in 3.4. There's a pull request reimplementing this for lossless WebP, but it needs more work to handle sRGB formats properly.

If you enable Force Png in the Project Settings, you should see automatic format detection working again.

josefkaragoli commented 2 years ago

If you enable Force Png in the Project Settings, you should see automatic format detection working again.

This doesn't work for images compressed to VRAM compression, only Lossless images:

EDIT: Sorry I see that you mentioned this, didn't read it well. It seems then that godot doesn't yet have a built-in VRAM compressed format for lum8 grayscale images?

Calinou commented 2 years ago

It seems then that godot doesn't yet have a built-in VRAM compressed format for lum8 grayscale images?

Is there such a format that is widely supported? Godot currently supports S3TC on desktop, ETC2 on mobile and BPTC on desktop (Windows/Linux only).

Godot will get ASTC support in the future for mobile (+ macOS ARM), but I don't know if it has a L8 format.

Zylann commented 6 months ago

Got linked to this proposal, and that might be useful for my terrain plugin as well, though I use the R8 format instead of L8. I use R8 to store terrain density maps. But Godot keeps importing them as RGB8, which is a waste of memory (and yet it's probably getting converted to RGBA8 in VRAM, as I read that drivers dont natively support it). It would help save memory if there was an import setting to respect the channels present in the file, or at least tell to load only one channel, or detect that only one channel is used.

BlueCube3310 commented 6 months ago

Is there such a format that is widely supported? Godot currently supports S3TC on desktop, ETC2 on mobile and BPTC on desktop (Windows/Linux only).

The closest would be RGTC_R with a R -> RGB swizzle, though it doesn't have an sRGB equivalent.