Skip to content

Add function to update Atlases (such as DecalAtlas) with changes to individual textures.#115653

Open
ColinSORourke wants to merge 1 commit into
godotengine:masterfrom
ColinSORourke:DecalDrawSync
Open

Add function to update Atlases (such as DecalAtlas) with changes to individual textures.#115653
ColinSORourke wants to merge 1 commit into
godotengine:masterfrom
ColinSORourke:DecalDrawSync

Conversation

@ColinSORourke
Copy link
Copy Markdown
Contributor

This is a feature enhancement for DrawableTextures, based on Rendering Meeting conversations with @QbieShay.

The desired behavior was to use DrawableTextures to animate Decals, however because Decals are read from a Decal Atlas, blits to the DrawableTexture would not update the Atlas unless fully rebuilt. This PR adds new methods, in both rendering servers, to allow redrawing singular textures in the Atlas without a full rebuild. This is currently only invoked by Drawable_Texture_Blit_Rect, but could also be useful for other cases where an Atlas uses a Texture that may have its data changed, such as Texture Update Partial

draw-decal.zip
Attached is a minimal project featuring DrawableTextures being synced to a Decal Atlas - Decal Atlas instantiates new Decals, each of which with their own DrawableTexture being faded by periodic Blit_rect calls.

Adds internal function Decal_Atlas_Update_texture / Texture_atlas_update_texture to TextureStorage. This is called when a DrawableTexture is blitted to sync the change to the atlas.
@ColinSORourke ColinSORourke marked this pull request as ready for review January 30, 2026 21:25
@ColinSORourke ColinSORourke requested a review from a team as a code owner January 30, 2026 21:25
@Calinou Calinou added this to the 4.x milestone Jan 30, 2026

CopyEffects *copy_effects = CopyEffects::get_singleton();
ERR_FAIL_NULL(copy_effects);
ERR_FAIL_COND(!decal_atlas.texture.is_valid());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
ERR_FAIL_COND(!decal_atlas.texture.is_valid());
ERR_FAIL_COND(decal_atlas.texture.is_null());

@akien-mga
Copy link
Copy Markdown
Member

Just a nitpick on the commit/PR title, it's not clear what "Atlas_Update_Texture" refers to. Identifiers with underscores should be reserved for actual references to code (with backticks), but there's no "Atlas_Update_Texture" code in this PR (there's texture_atlas_update_texture in GLES3 and it's named differently in RD.

So it would be better to use plain English than proto-code for this. See https://github.com/godotengine/godot/blob/master/CONTRIBUTING.md#format-your-commit-messages-with-readability-in-mind for details on how we prefer commit messages to be written.

@ColinSORourke ColinSORourke changed the title Add "Atlas_Update_Texture" to allow DecalAtlas to sync with DrawableTexture updates Add function to update Atlases (such as DecalAtlas) with changes to individual textures. Feb 2, 2026
@coobenguy
Copy link
Copy Markdown

This would also allow for animated light projectors right?

@Calinou
Copy link
Copy Markdown
Member

Calinou commented Feb 20, 2026

This would also allow for animated light projectors right?

Projectors use their own atlas, but it works in the same way as decals. I didn't test if projectors work with animated DrawableTextures now, but it should be easy to implement if it doesn't work already with the PR.

@ColinSORourke
Copy link
Copy Markdown
Contributor Author

@Calinou @coobenguy I just tested this, and it seems like the case!

I set up a Spotlight3D, and had a GDScript initialize the Light_Projector texture to a new DrawableTexture, and then a timer callback to blit the Light_Projector between two possible textures. It correctly 'animated' the light projector

@mertkasar
Copy link
Copy Markdown
Contributor

A little test on DrawableTexture as projector... literally... 👀

control-projector-1080.mp4

@Calinou
Copy link
Copy Markdown
Member

Calinou commented Apr 2, 2026

I wonder if this could be called in ViewportTexture when it's redrawn. While we want to encourage DrawableTexture when possible as it's less demanding, some use cases are better served by ViewportTexture.

If the Viewport has its update mode set correctly, it should only redraw when needed (or only redraw once), so there shouldn't be a significant performance cost otherwise. It should suppress the need for more demanding get_texture() workarounds, which should overall be a performance win. Implementing this would effectively close #73400.

@TheMagnat
Copy link
Copy Markdown

I wonder if this could be called in ViewportTexture when it's redrawn. While we want to encourage DrawableTexture when possible as it's less demanding, some use cases are better served by ViewportTexture.

If the Viewport has its update mode set correctly, it should only redraw when needed (or only redraw once), so there shouldn't be a significant performance cost otherwise. It should suppress the need for more demanding get_texture() workarounds, which should overall be a performance win.

I've created a PR on the branch from this PR to add this feature : ColinSORourke#1
But I'm not certain on my implementation, this feature require managing proxy texture, update the used variable so that the Viewport get updated on visible update mode. Maybe we should valid this feature directly and add the viewport feature on another PR ?

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.

7 participants