godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Add a bit depth property to NoiseTexture #10532

Open jabcross opened 2 months ago

jabcross commented 2 months ago

Describe the project you are working on

A shader-heavy game with lots of randomly generated textures

Describe the problem or limitation you are having in your project

The built-in noise texture resource doesn't give you the option of which precision to use, being currently hardcoded to use L8.

https://github.com/godotengine/godot/blob/568589c9d8c763bfb3a4348174d53b42d7c59f21/modules/noise/noise.cpp#L159

This is not enough for shaders with high-frequency elements such as starfields, where we try to detect single-pixel peaks and valleys in a noise texture.

Even though there are more performance-efficient ways to render this type of effect, it is useful to use the noise generator parameters to find good distributions.

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

Add a dropdown resource parameter to select the bit depth and reference it when generating the texture.

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

n/a

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

No, since the intended effect is to be able to use the inspector to visually tweak shaders.

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

Should be part of every noise generator.

Calinou commented 2 months ago

GradientTexture has an Use HDR property which makes it generate a RGBAH instead of RGBA8. We could add the same property to NoiseTexture.

However, while there is a L8 format, there is no LH or LF format. You need to use RH or RF respectively, which maps luminance to the red channel instead of being grayscale. To preserve its grayscale look, we'd need to switch to RGBH or RGBF instead (which requires much more memory).

jabcross commented 2 months ago

GradientTexture has an Use HDR property which makes it generate a RGBAH instead of RGBA8. We could add the same property to NoiseTexture.

However, while there is a L8 format, there is no LH or LF format. You need to use RH or RF respectively, which maps luminance to the red channel instead of being grayscale. To preserve its grayscale look, we'd need to switch to RGBH or RGBF instead (which requires much more memory).

Is there anything preventing the difference in look from being worked around in the shader itself? Since that's the main application of noise textures, I don't think it would be a big issue.

Being able to be specific with the format (allowing for R32, RF, etc), and potentially allowing for arbitrary format and just adding a new independently-seeded noise channel for each format channel would be the logical generalization, I think.

Calinou commented 2 months ago

Is there anything preventing the difference in look from being worked around in the shader itself? Since that's the main application of noise textures, I don't think it would be a big issue.

We can't use a dedicated shader only when a NoiseTexture is displayed, as the NoiseTexture may only be a single part of an entire material (e.g. BaseMaterial3D for 3D materials).

jabcross commented 2 months ago

That makes sense. That ties into the composability issues of shaders in general, I suppose. The only way to work around that currently is through a ViewportTexture, right?

Maybe we should have a CanvasItemTexture that just automates the whole viewport composition process. 🤔

Either way, this change wouldn't break current behavior, so maybe a warning is all that is needed. Or making the composite material built-in shaders aware of the difference between image formats.