godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.82k stars 21.14k forks source link

Initially dragging textures (PNG, JPG) from FileSystem into shader parameters lags #88060

Open bikemurt opened 9 months ago

bikemurt commented 9 months ago

Tested versions

System information

Godot v4.2.1.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3050 Ti Laptop GPU (NVIDIA; 31.0.15.5123) - 12th Gen Intel(R) Core(TM) i5-12500H (16 Threads)

Issue description

After dragging a texture from FileSystem to a shader parameter for the first time, the lag was something like 10 seconds -I thought Godot was going to crash. If you drag and hold and wait long enough you can actually drop into the shader parameter but the UI is noticeably laggy during this portion.

After clearing the shader parameter and dragging it in again, there was no lag. So it only happens on the first time.

Happens with JPG, PNG

It does NOT happen with DDS, so I think this points to some sort of problem with the import pipeline.

Steps to reproduce

To reproduce, copy/paste the shader below into a new ShaderMaterial, load the texture into the FileSystem, and try dragging the pebbles_01.jpg from the FileSystem into the Texture 2 parameter.

shader_type spatial;

uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D splatMap;

void fragment() {
    // Called for every pixel the material is visible on.
}

pebbles_02

Minimal reproduction project (MRP)

DragTextureIssue.zip

Calinou commented 9 months ago

This is expected, because the texture needs to be imported with VRAM compression the first time you're using it in a 3D context. VRAM compression takes a while for large textures, and there's not much we can do to speed this up until Betsy is integrated (which will take a while to happen, if ever).

The alternative is to import the texture with lossless compression (so you can see it apply faster) and immediately import it with VRAM compression afterwards, but this will take more time than importing it directly with VRAM compression.

Do you see a progress dialog appear when performing the initial drag-and-drop operation? If not, we should look into fixing that, but it's all we can aim to do.

bikemurt commented 9 months ago

I don't know enough about image formats and compression to have a really intelligible conversation about this - but I am wondering if the DDS format is fine because it's basically already in a format easily digestible for VRAM?

As per loading bar, no. The UI froze for about 10 seconds and then when the icon appeared to drop the texture in, it was lagging about a second behind my mouse movement.

Is there no way to trigger the VRAM compression upon first importing the file rather than when it is first used in the rendering pipeline?

Edit: I reread your comment and I see what you're saying. Godot doesn't know if the texture will be used in a 3D context so it can't apply the VRAM compression until it does.

Calinou commented 9 months ago

but I am wondering if the DDS format is fine because it's basically already in a format easily digestible for VRAM?

Yes – in fact, Godot doesn't even import DDS textures. It reads them directly instead.

Is there no way to trigger the VRAM compression upon first importing the file rather than when it is first used in the rendering pipeline?

When a texture is first imported, we don't know in advance whether it'll be used in a 3D context yet. Importing all textures with VRAM compression in the hope that they will eventually be used in 3D would waste resources, as this won't happen with textures used in a 2D project or UI textures.

quackmarx commented 1 month ago

Just linking a previous discussion on the topic: #78471

See my last comment on the discussion for arguments as to why this should be fixed.

When a texture is first imported, we don't know in advance whether it'll be used in a 3D context yet. Importing all textures with VRAM compression in the hope that they will eventually be used in 3D would waste resources, as this won't happen with textures used in a 2D project or UI textures.

I think it's important we find a place to put this loading that is not during a UI/UX operation such as drag and drop. Perhaps after the drag/drop has concluded, sacrificing some of the preview functionality in the viewport?

The alternative is to import the texture with lossless compression (so you can see it apply faster) and immediately import it with VRAM compression afterwards, but this will take more time than importing it directly with VRAM compression.

I would personally prefer this. I think a little but of extra load time is for me preferred to hanging up the editor mid-drag.