X Tutup
Skip to content

Editor additions for MipMaps and rd_textures#109004

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
DDarby-Lewis:master
Feb 27, 2026
Merged

Editor additions for MipMaps and rd_textures#109004
Repiteo merged 1 commit intogodotengine:masterfrom
DDarby-Lewis:master

Conversation

@DDarby-Lewis
Copy link
Contributor

@DDarby-Lewis DDarby-Lewis commented Jul 26, 2025

This PR adds mipmap selector for texture previews. The mipmap selector only shows if there is at least one mipmap level.

image image

It also enables texture previews for rd_textures.
Finally there is a small addition for rd_textures using RenderingDevice.DATA_FORMAT_R8G8B8A8_UNORM format to properly create their SRGB view - bringing them inline with the same assumptions used by other textures with the R8G8B8A8 format that they will be in SRGB.

The project this is being developed for utilises texture generation with compute textures.

I would also like to consider if it would be possible/reasonable to make the TexturePreview class accessible from GDScript so that my procedural texture class could use it without having to write that class into the core engine?

Bugsquad edit: Closes godotengine/godot-proposals#12873

@Ivorforce
Copy link
Member

Ivorforce commented Jul 26, 2025

Hello, thank you for contributing to Godot engine! This looks like an interesting addition :)

New feature PRs should be linked to a feature proposal. I quickly searched through and found nothing of the sort, so you might have to open one yourself. You might also be interested in reading into the Contributions Workflow.

@DDarby-Lewis
Copy link
Contributor Author

I would appreciate any thoughts or comments on this, it's my first PR (and second contribution) for Godot.

Something else to consider here is if I could add some more generic way to make the texture preview applicable, since would like to move my procedural texture class from using Texture2DRD to being based on Texture2D and handling the other parts myself.
Reason being that sometimes I would need to be able to switch from using a rd texture and other times a texture 2d as a the rendering server side, as decals for example don't support rd textures.
My current solution is to have two separate classes, with separate bases, but that is messy since I cannot switch a texture from one to the other easily.
I was thinking perhaps to use utilise a some general logic like if the class is Texture2D, and it has functions for _get_mipmap_count and _get_format (inline with the existing override functions for Texture2D class) to provide the additional data that the texture preview is after then it will apply a preview.

Right now the texture preview class contains a lot of logic that is repeated for various texture subclasses, and it would be better OOP if that logic lived on the subclasses (perhaps even on an override function), each class could even mark itself with a const if it wanted texture preview to apply. This would both DRY up the TexturePreview class and move the logic to the responsible subclasses. Thoughts?

If there is an appetite for a feature that adds a generic procedural texture class to the core engine I can look at converting my GDscript work into c++ after this, but that would be good chunk of work since it uses a custom set of compute pipeline resources along side some.

@DDarby-Lewis
Copy link
Contributor Author

Hello, thank you for contributing to Godot engine! This looks like an interesting addition :)

New feature PRs should be linked to a feature proposal. I quickly searched through and found nothing of the sort, so you might have to open one yourself. You might also be interested in reading into the Contributions Workflow.

Thank you - I will do that :)

@DDarby-Lewis
Copy link
Contributor Author

@Ivorforce I have added a feature proposal here: godotengine/godot-proposals#12873

@BlueCube3310
Copy link
Contributor

I support this, the ability to visualize mipmaps is useful in many cases. Could the selection settings be changed to a horizontal slider, though? I feel as if that would make it easier to use.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change needed? What would happen without it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pre-existing issues with rd textures but is more of an issue now that rd textures are supported in the texture preview, in that the preview is 2D and if your texture is for 3D it will be linear, so it displays wrong without this change.
You can see the mentioned issue for screenshots.
I figure that since it is connected to related functionality in the TexturePreview it makes sense to include both.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The display of hdr textures (f16, f32) as linear in 2D is expected behavior, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this only affects 8 bit formats (the ones with an assigned srgb_format in engine).
Basically it gives parity for the rd textures to what standard 2d textures already have.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't test it, but I'm still skeptical about this.

texture_create_shared is necessary, otherwise, you might accidentally release the rd_texture, and it might wrongly assign a srgb format texture to rd_texture.

Note that srgb format textures are generally used in 3D for samplers to automatically perform sRGB → linear conversion. In 2D you should use non-srgb formats.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What 8 bit texture do you use? R8G8B8A8 should work fine, but R8 or R8G8 or R8G8B8 won't, their srgb versions' device support is not good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What 8 bit texture do you use? R8G8B8A8 should work fine, but R8 or R8G8 or R8G8B8 won't, their srgb versions' device support is not good.

R8G8B8A8 is what I am using - you can see screenshots on here: #103836
The screenshots are of R8G8B8A8 rd textures.
If you can show an example of it working with the current code or with less/other modifications I'd be happy to adjust what I have in here.

Copy link
Contributor

@beicause beicause Jul 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I finally tested it with https://github.com/beicause/godot-demo-projects/blob/rasterize-mesh-texture/rendering/mesh_texture_rd/mesh_texture_rd.gd and can confirm this issue. Thank you for your patience.

This should be in a separate PR though. I'll also take a look. Edit: See #109030

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for testing - it's always good to have a second set of eyes confirm :)
I'll look at creating a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have taken a look at the PR you have raised and we have had slightly different tacts - I haven't added the shared formats under the assumptions that it would prevent any disruption to work already relying on the current way that it works and instead I only create the srgb view if the associated shared format is already present (again on the assumption that if anyone has included theses then they are expecting the to be used).

I then include the following lines in my procedural texture generator in my project:

    if _format == RenderingDevice.DATA_FORMAT_R8G8B8A8_UNORM:
        format.add_shareable_format(_format)
        format.add_shareable_format(RenderingDevice.DATA_FORMAT_R8G8B8A8_SRGB)

Do we need to have a discussion on the best way to approach this? If the fact that it is missing is purely bugged behaviour then I'd agree to just adding the formats. However if, as you are pointing out in your PR, it may lack full support, perhaps making the approach of only adding a view when required preferable?

@DDarby-Lewis
Copy link
Contributor Author

I support this, the ability to visualize mipmaps is useful in many cases. Could the selection settings be changed to a horizontal slider, though? I feel as if that would make it easier to use.

I looked at this but on the scale of this UI element a slider is fiddly and the selection boxes show clearly the mipmap number as well as matching the visuals for the channel selections.

@DDarby-Lewis
Copy link
Contributor Author

I will address the linting issues tomorrow and repush, from what I understand I should undo my commit and force push a single commit with the changes, is that correct?

@DDarby-Lewis
Copy link
Contributor Author

I also don't have a good icon for the mipmap toggle, if anyone can suggest something that'd be great!

@Ivorforce
Copy link
Member

I will address the linting issues tomorrow and repush, from what I understand I should undo my commit and force push a single commit with the changes, is that correct?

Yes, at least eventually it should be one commit. It's not that important until just before merge though.

@DDarby-Lewis DDarby-Lewis force-pushed the master branch 2 times, most recently from e79a2ca to a891f15 Compare July 27, 2025 13:36
@LiveTrower
Copy link
Contributor

I think it would be better to do this with a SpinBox:

example.mp4

I also see that there's a missing implementation for mipmap pre-visualization for other texture types that support mipmaps, such as Texture3D, CubeMap, Texture2DArray, etc.

One thing I think would also be good is to add a project or editor setting that allows switching between linear or nearest filtering, as mipmaps are normally used with linear filtering.

@DDarby-Lewis
Copy link
Contributor Author

DDarby-Lewis commented Jul 27, 2025

@LiveTrower I feel that the radio button selectors are both easier to use and nicer looking, but I'm happy to be outvoted and adjust it 😄

As for mipmap visuals on other texture types, I have here only added a mipmap option to textures in the TexturePreview that support retrival of the number of mipmaps - I think it would perhaps make sense to expand the Texture class (or subclasses) with an implementation of the get_format function (with assisiated override _get_format) and a get_mipmap_count (and assositated _ override) as suggested in the feature proposal here: godotengine/godot-proposals#12873
That way we could enable the texture preview more widely and rely on those functions without adding custom logic per class.
However, that expansion seems out of scope for this change to add the initial functionality.
Perhaps if you support it or have thoughts you could add them to that discussion?

On the matter of linear vs nearest - I am happy with nearest for texture previews (more clearly shows the "data" in the image for my purposes) but I'd happily support the addition of a selector for filtering 👍

@LiveTrower
Copy link
Contributor

@DDarby-Lewis I don't think it should be difficult to add support for the other texture previews. Similar to how you modified texture_editor_plugin, it should be something similar for texture_3d_editor_plugin, texture_layered_editor_plugin, and texture_region_editor_plugin.

@arkology
Copy link
Contributor

arkology commented Aug 1, 2025

I think it will be good to:

  1. Split changes in core and editor into 2 PRs.
  2. For editor part take into account the following PRs: TextureEditors: Compile shader/material only once #104488 and ColorChannelSelector: add tooltip, fix toggle_button repositioning and channels autotranslation #104474.

@DDarby-Lewis
Copy link
Contributor Author

So along with the addition of the virtual _get_image function this allows the texture preview to apply to any texture with a working get_image function - I have disabled for any class called GradientTexture.* for obvious reasons. If any has any other textures to ignore here please let me know. I'd like this to get merged soon so if anyone has final comments please add them and then I'll split into two MRs as suggested.

MR 1: Editor additions
MR 2: core function enhancements

@DDarby-Lewis DDarby-Lewis requested a review from beicause August 1, 2025 22:11
@DDarby-Lewis DDarby-Lewis requested review from a team as code owners February 10, 2026 18:38
@AThousandShips
Copy link
Member

AThousandShips commented Feb 10, 2026

A lot of unrelated code was included in this PR, marking as draft until that's resolved to prevent additional invalid review requests

@AThousandShips
Copy link
Member

Now fixed, you just need to re-apply the documentation changes (you undid them) and fix the format

@DDarby-Lewis
Copy link
Contributor Author

@AThousandShips Sorry I had accidentally committed the ps script I was using for local testing - I have now removed that.
Can you advise if you think anything else here is unrelated? From my perspective, this is what is required to implement the feature holistically without adding tech debt.

@AThousandShips
Copy link
Member

Seems nothing is left now, but you added a bunch of other code at first with the merge commit from master (that's why it added a ton of unrelated review requests), but that was removed with the commit that added the unrelated script

@DDarby-Lewis
Copy link
Contributor Author

Seems nothing is left now, but you added a bunch of other code at first with the merge commit from master (that's why it added a ton of unrelated review requests), but that was removed with the commit that added the unrelated script

Ah Ok - yes that was me doing something daft on rebase.

I think the PS script was actually pretty helpful but if it isn't requried here so I've removed it. Hopefully the CI passes now - if not, I'll be baffled!

@AThousandShips
Copy link
Member

I'll run it once you've fixed the documentation

@AThousandShips
Copy link
Member

You deleted a lot of unrelated documentation, did you run --doctool with a different build?

@DDarby-Lewis
Copy link
Contributor Author

@AThousandShips I believe I have addressed the docs now - can you help me understand how changes for other classes haven't had their docs already merged into master when the changes themselves were merged?
Doesn't change anything - I'm just not should how this would be happening.

^ Scrap that I can see what I am doing wrong - I am not rebuilding before running the docs tool!!! My mistake. Addressing now.

@AThousandShips
Copy link
Member

In the future I suggest looking at the "files changed" tab whenever anything goes wrong to see what maintainers are talking about, it shows the changes to master in the PR

@DDarby-Lewis
Copy link
Contributor Author

@AThousandShips, everything is passing here now and it all seems ready, can it be approved and merged?

@AThousandShips
Copy link
Member

It needs more maintainers to review and approve it, it has one already

@DDarby-Lewis
Copy link
Contributor Author

I can't see the rules for minimal approvals, do you know how many it requires?

@AThousandShips
Copy link
Member

It depends from case to case, it's not a simple case of rules it's a matter of specific needs of the project

Copy link
Member

@KoBeWi KoBeWi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The editor changes look fine, but there is one potential crash that needs to be addressed.

Copy link
Member

@KoBeWi KoBeWi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The editor changes look good.

image = atlas->get_image();
}
} else if (rd_texture.is_valid()) {
if (RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also needs safeguard

Suggested change
if (RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
if (RD::get_singleton() && RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - Really at some point all the Texture2D classes should have proper implementations of the get_image, has/get_mipmaps and similar functions rather than this logic living here, but happy to avoid the scope here creeping any further.

@Calinou
Copy link
Member

Calinou commented Feb 18, 2026

This fails to compile for me on Linux/GCC when rebased on top of master:

Generating editor/themes/builtin_fonts.gen.h ...
In file included from editor/scene/texture/.scu/scu_editor_scene_texture.gen.cpp:5:
./editor/scene/texture/texture_editor_plugin.cpp: In function 'Image::Format get_texture_2d_format(const Ref<Texture2D>&)':
./editor/scene/texture/texture_editor_plugin.cpp:137:38: error: 'RD' has not been declared; did you mean 'RID'?
  137 |         if (rd_texture.is_valid() && RD::get_singleton() && RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
      |                                      ^~
      |                                      RID
./editor/scene/texture/texture_editor_plugin.cpp:137:61: error: 'RD' has not been declared; did you mean 'RID'?
  137 |         if (rd_texture.is_valid() && RD::get_singleton() && RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
      |                                                             ^~
      |                                                             RID
./editor/scene/texture/texture_editor_plugin.cpp: In function 'int get_texture_mipmaps_count(const Ref<Texture2D>&)':
./editor/scene/texture/texture_editor_plugin.cpp:160:21: error: 'RD' has not been declared; did you mean 'RID'?
  160 |                 if (RD::get_singleton() && RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
      |                     ^~
      |                     RID
./editor/scene/texture/texture_editor_plugin.cpp:160:44: error: 'RD' has not been declared; did you mean 'RID'?
  160 |                 if (RD::get_singleton() && RD::get_singleton()->texture_is_valid(rd_texture->get_texture_rd_rid())) {
      |                                            ^~
      |                                            RID

I have tried a fresh build with no cache just in case, and it still occurs. I'm using scons scu_build=all, but the issue occurs without it too.

@DDarby-Lewis
Copy link
Contributor Author

DDarby-Lewis commented Feb 23, 2026

@Calinou could that possibly be a local issue for you? It hasn't occurred on the Linux compile in the CI pipeline.
Actually after a rebase this is happening for me too - I take it one of the includes has changed... I'll update.

@DDarby-Lewis
Copy link
Contributor Author

@Calinou I have pushed a fix for that. Would love to merge this so I can stop having to patch fixes in from changes to main ;)

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected. Code looks good to me.

I agree we should implement mipmap previewing support to types other than Texture2D (that is: Texture2DArray, Texture3D, Cubemap, and CubemapArray), but this can be added in a future PR. Having support for mipmap previewing on Texture2D will already be pretty useful for VFX use cases, as well as troubleshooting procedural texture generation with the Image class.

@Repiteo
Copy link
Contributor

Repiteo commented Feb 27, 2026

Thanks! Congratulations on your first merged contribution! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add LOD to TexturePreview and improve rd_texture usage
X Tutup