Fix VisualShader conversion failing with subresources#109375
Fix VisualShader conversion failing with subresources#109375Repiteo merged 1 commit intogodotengine:masterfrom
Conversation
|
The problem with this solution is that VisualShader nodes have to count the embeds manually. If someone adds a new node with a resource, but does not mark embed, it will miss the error. |
61b7700 to
d3c4859
Compare
db8c2ec to
e0cc9f0
Compare
|
Came back to this. I wonder how we feel about adding a |
Assuming you are talking about VisualShaderNodeCustom - VisualShaderNodeCustom cannot have Resource Embeds, nothing in the current API provides that functionality unless I am misunderstanding.
We talked about this in the Rendering Meeting today (Aug.20) (You were there :) ) and determined hint_default is not a workable feature. Conclusion we reached in the Rendering Meeting for the issue is to throw a warning popup when the conversion plugin is called via Editor, and fall back to throwing an Error (like the current solution) when the conversion is initiated via code. I will adjust my fix to throw the popup when I have some spare time |
No, adding a new visual shader node type in the engine. This PR modifies many classes, and in the future there may be more classes that will need similar checks. |
Tracking embeds is necessary to catch and communicate this bad conversion behavior. I think the responsibility of tracking embeds is best assigned to individual node classes. Currently only 6 VisualShaderNode classes can have embedded resources, and I would say safe handling of resources on future node classes is important, and low cost. I have a hard time envisioning an alternative architecture that defers the responsibility of tracking embeds somewhere else? Managing this information from the Visual Shader Editor Plugin seems like it would require more work than having each node track itself, and I don't know if the Visual Shader resource Class has enough info to do any of this tracking. |
e0cc9f0 to
c299253
Compare
|
@KoBeWi Talked about it in the rendering meeting today, and have updated the PR with a different architecture for the fix. This single function in the VisualShader class should be able to catch which child nodes have embedded resource properties without requiring any overhead on the VisualShaderNode classes |
c299253 to
71849c8
Compare
|
I tested the MRP from #101375 with the newest version of this PR and it doesn't seem to do anything. Conversion is still broken and there is no error/warning. Maybe I'm doing something wrong, idk. |
71849c8 to
1bd95e5
Compare
|
@KoBeWi My bad! Silly mistake, I've pushed a fix. I changed an inner loop variable name 'i'->'j' to satisfy the code check that inner loop should not use same name as outer loop, but forget to replace in a few relevant locations. Fixed, tested, works. |
1bd95e5 to
3983d2d
Compare
| int embed = vshader->has_node_embeds(); | ||
| ERR_FAIL_COND_V_MSG(embed == 2, Ref<Resource>(), "Cannot convert VisualShader to GDShader because VisualShader has embedded subresources."); | ||
| if (embed == 1) { | ||
| WARN_PRINT("Visual Shader conversion cannot convert embedded resources. Resource references from Nodes will have to be rebound as ShaderParameters on a Material"); |
There was a problem hiding this comment.
"embedded" is not correct here. They are not embedded, they are external dependencies of the shader.
btw are the shader parameters automatically created?
There was a problem hiding this comment.
Updated the language on the error.
As far as I can tell, yes the Shader Parameters are automatically created. A Texture2D Node (which could have an embedded texture) is converted to a Uniform in the GD Shader Code, which will be recognized as a Shader Parameter.
The VisualShader in the MRP has 2 Texture2D Nodes, they convert to code
uniform sampler2D tex_frg_44;
uniform sampler2D tex_frg_43;
And when the converted GDShader is attached to a ShaderMaterial, the uniforms show up as a parameter again
| g->nodes[p_id].position = p_position; | ||
| } | ||
|
|
||
| // Returns 0 if no embeds, 1 if external embeds, 2 if builtin embeds |
There was a problem hiding this comment.
This sounds like it should be an enum, but since it's an editor one-time helper, hard-coding is fine too.
|
Looks fine now, but I'd change the warning to a toaster message, as it's easy to miss. Also converting the shader from the inspector results in clearing the property if there are sub-resources. godot.windows.editor.dev.x86_64_F7AZEe8BRj.mp4This could be avoided by returning the same shader instead of null. |
3983d2d to
8657fe3
Compare
|
@KoBeWi Updated warning language, and changed to throw a Toaster Message (when it can - I think there are cases where a conversion plugin can be invoked outside of editor)
Made this update too, although I think it'd be preferable if the Inspector Dock handled a null return and recognized the value as unchanged. Looking for the file that manages that ;) |
|
Looks like easy fix: |
8657fe3 to
cabad7a
Compare
|
Added a catch in Editor_Resource_Picker conversion to handle being given null by a failed conversion. Returned the Conversion plugin to always return null in a failed conversion. Also added |
cabad7a to
914b482
Compare
|
Pushed a build addressing @KoBeWi and @AThousandShips comments. |
Potentially resolves godotengine#101375 VisualShader now has a has_node_embeds function that runs through it's child nodes to find embedded resources via object properties. Conversion plugin uses this function to catch the error.
914b482 to
c4559c0
Compare
|
Thanks! |
|
Cherry-picked for 4.5.2. |
(Attempts to) Resolve: #101375
Visual Shaders can have Subresources such as Textures embedded directly in the Visual Shader, and some users find this desirable to better preview the Visual Shader's behavior. However, this breaks the conversion from Visual Shader to Text GDShader because a Text GDshader cannot have SubResources (the appropriate place for these resources would be as a Shader Parameter on a ShaderMaterial).
This PR aligns with @QbieShay's suggestion that
And resolves the issue by adding a has_node_embeds function to the VisualShader class. Has_node_embeds iterates over the child nodes, and searches through the object properties for embedded resources. The conversion plugin calls this function to catch and throw appropriate errors/warnings.
Note: ConversionPlugin fail states can cause a crash in FileSystem_Dock.cpp - I've mirrored a catch for that from #109369 to here.
This PR could unblock #102918, which could decrease file sizes and improve load times. Would require a little more work to have that PRs code handle a failed conversion.
More ideal solutions could be developed in the future such as:
But I believe this code is still a necessary step to resolve the core error (Conversion deleting subresources) and to track VisualShader subresources for compatibility with future changes.