godotengine / godot

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

ViewportTextures work in-editor, appear solid purple in-game. #74331

Open rlenhub opened 1 year ago

rlenhub commented 1 year ago

Godot version

4.0.stable.official

System information

Windows 11, Forward+, Nvidia RTX 3060 (528.49)

Issue description

I have a SubViewportContainer and a sub-viewport. Inside this viewport, I have a MeshInstance with a ViewportTexture as the albedo, assigned another viewport containing some Control nodes. In the editor, it appears to correctly render the assigned viewport. However, when I run the scene, the texture turns into a solid purple.

viewporthierarchy

Steps to reproduce

  1. Create new 3D scene.
  2. Add a Control node under the root.
  3. Add a SubViewportContainer under the Control.
  4. Parent a SubViewport to the SubViewportContainer.
  5. Add a Camera3D and a MeshInstance3D to the SubViewport.
  6. Create another SubViewport under the first SubViewport.
  7. Add a Control node, along with some visible UI elements.
  8. Create a new material for the mesh instance, with a ViewportTexture as the albedo.
  9. Assign the lowest viewport to the texture.
  10. Observe the mesh properly rendering the viewport in the editor.
  11. Run the scene, observe that the viewport texture only works in the editor.

Alternatively, run the minimal reproduction project.

Minimal reproduction project

Minimal Reproduction Project

Sauermann commented 1 year ago

It your MRP you use SubViewport as a Skeleton3D for the MeshInstance3D. But a SubViewport is not a Skeleton3D. Maybe it should be considered a bug, that non-Skeleton3D nodes can be assigned to a Skeleton3D?

image

rlenhub commented 1 year ago

Unfortunately, it looks like that wasn't causing any problems. I added a skeleton and attached the mesh to it, and nothing seems to have changed.

rlenhub commented 1 year ago

So... after some testing, I've discovered that it has nothing to do with nested subviewports. Turns out, ViewportTextures just straight up don't work anymore.

bru

rlenhub commented 1 year ago

GL Compatibility renderer does not fix this problem.

glcompat

rlenhub commented 1 year ago

It's not exclusive to Controls either.

no3deither

EDIT: 2D nodes do not work either. Nothing will render.

no2deither

Rindbee commented 1 year ago
ERROR: Viewport Texture must be set to use it.
   at: get_height (scene/main/viewport.cpp:116)
ERROR: Viewport Texture must be set to use it.
   at: get_width (scene/main/viewport.cpp:111)
ERROR: Node not found: "Control/SubViewportContainer/SubViewport/SubViewport" (relative to "main").
   at: get_node (scene/main/node.cpp:1364)
ERROR: ViewportTexture: Path to node is invalid.
   at: setup_local_to_scene (scene/main/viewport.cpp:76)

This may have something to do with the order in which the nodes are entered, and whether and when they are redrawn.

nested_viewports-1.zip

rlenhub commented 1 year ago
ERROR: Viewport Texture must be set to use it.
   at: get_height (scene/main/viewport.cpp:116)
ERROR: Viewport Texture must be set to use it.
   at: get_width (scene/main/viewport.cpp:111)
ERROR: Node not found: "Control/SubViewportContainer/SubViewport/SubViewport" (relative to "main").
   at: get_node (scene/main/node.cpp:1364)
ERROR: ViewportTexture: Path to node is invalid.
   at: setup_local_to_scene (scene/main/viewport.cpp:76)

This may have something to do with the order in which the nodes are entered, and whether and when they are redrawn.

nested_viewports-1.zip

Thank you so much! The texture seems to only be able to find it's viewport when it's mapped to the mesh via the renderer, and not via a scene-unique version of the mesh itself, as I was attempting. This is a good enough workaround.

dimroc commented 1 year ago

I had a similar issue and solved it by setting "Local to Scene" on the MeshInstance3D with the material using the Viewport Texture.

Rindbee commented 1 year ago

During scene initialization, resources with resource_local_to_scene enabled will call setup_local_to_scene() after all nodes in the scene have been setup.

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L464-L468

The same goes for subresources within resources. They may be cached in resources_local_to_scene when duplicating or configuring.

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L317

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L332

But the PROPERTY_USAGE_STORAGE flag must be enabled. Otherwise, setup_local_to_scene() on the subresource will not be called (Subresources are not cached).

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/core/io/resource.cpp#L232-L234

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/mesh.cpp#L1704-L1711

SouthBear77 commented 1 year ago

I solved it with Local to Scene: On for the Mesh Resource, Material Resource, and Albedo Texture Resource as shown below.

So it wasn't a bug. But the way to show the UI in 3D space is more complicated than in other engines.

Anyway, thanks.

Gui3D +- SubViewport

+- MeshInstance3D

MeshInstance3D

Mesh Resource Local to Scene: On

Material Resource Local to Scene: On

Albedo Texture (ViewportTexture) Viewport Path: /Gui3D/SubViewport Resource Local to Scene: On

2023년 5월 25일 (목) 오후 4:14, 风青山 @.***>님이 작성:

During scene initialization, resources with resource_local_to_scene enabled will call setup_local_to_scene() after all scene nodes have been setup.

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L464-L468

The same goes for subresources within resources. They may be cached in resources_local_to_scene when duplicating or configuring.

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L317

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L332

But the PROPERTY_USAGE_STORAGE flag must be enabled. Otherwise, setup_local_to_scene() on the subresource will not be called.

https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/core/io/resource.cpp#L232-L234

— Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/74331#issuecomment-1562398079, or unsubscribe https://github.com/notifications/unsubscribe-auth/AU7XGOQ5MQPAAB5QMZFSPKLXH4BFHANCNFSM6AAAAAAVPGILKE . You are receiving this because you commented.Message ID: @.***>

Rindbee commented 1 year ago

I solved it with Local to Scene: On for the Mesh Resource, Material Resource, and Albedo Texture Resource as shown below.

This solution works for other mesh types. Not available for the case in ArrayMesh (the type of mesh used in MRP). The surface_0/material property does not have PROPERTY_USAGE_STORAGE enabled.

elvisish commented 11 months ago

I solved it with Local to Scene: On for the Mesh Resource, Material Resource, and Albedo Texture Resource as shown below. So it wasn't a bug. But the way to show the UI in 3D space is more complicated than in other engines. Anyway, thanks. Gui3D | +- SubViewport | +- MeshInstance3D MeshInstance3D Mesh Resource Local to Scene: On Material Resource Local to Scene: On Albedo Texture (ViewportTexture) Viewport Path: /Gui3D/SubViewport Resource Local to Scene: On 2023년 5월 25일 (목) 오후 4:14, 风青山 @.>님이 작성: During scene initialization, resources with resource_local_to_scene enabled will call setup_local_to_scene() after all scene nodes have been setup. https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L464-L468 The same goes for subresources within resources. They may be cached in resources_local_to_scene when duplicating or configuring. https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L317 https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L332 But the PROPERTY_USAGE_STORAGE flag must be enabled. Otherwise, setup_local_to_scene() on the subresource will not be called. https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/core/io/resource.cpp#L232-L234 — Reply to this email directly, view it on GitHub <#74331 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AU7XGOQ5MQPAAB5QMZFSPKLXH4BFHANCNFSM6AAAAAAVPGILKE . You are receiving this because you commented.Message ID: @.>

Confirmed, this works to fix the purple in 4.1.1, but I'm not using a material override, I'm using a PlaneMesh with viewport texture as a material: image

TSikavo commented 5 months ago

The solution turned out to be much simpler than it seemed. All you have to do is move the material to GeometryInstance3D Знімок екрана з 2024-04-09 21-20-14

Medie1 commented 2 months ago

I solved it with Local to Scene: On for the Mesh Resource, Material Resource, and Albedo Texture Resource as shown below. So it wasn't a bug. But the way to show the UI in 3D space is more complicated than in other engines. Anyway, thanks. Gui3D | +- SubViewport | +- MeshInstance3D MeshInstance3D Mesh Resource Local to Scene: On Material Resource Local to Scene: On Albedo Texture (ViewportTexture) Viewport Path: /Gui3D/SubViewport Resource Local to Scene: On 2023년 5월 25일 (목) 오후 4:14, 风青山 @.>님이 작성: During scene initialization, resources with resource_local_to_scene enabled will call setup_local_to_scene() after all scene nodes have been setup. https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L464-L468 The same goes for subresources within resources. They may be cached in resources_local_to_scene when duplicating or configuring. https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L317 https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/scene/resources/packed_scene.cpp#L332 But the PROPERTY_USAGE_STORAGE flag must be enabled. Otherwise, setup_local_to_scene() on the subresource will not be called. https://github.com/godotengine/godot/blob/4c677c88e918e22ad696f225d189124444f9665e/core/io/resource.cpp#L232-L234 — Reply to this email directly, view it on GitHub <#74331 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AU7XGOQ5MQPAAB5QMZFSPKLXH4BFHANCNFSM6AAAAAAVPGILKE . You are receiving this because you commented.Message ID: @.>

This did it for me, when using a MeshInstance3D adding a SubViewport to it and a Control node to the SubViewport to show 2D UI on a 3D mesh, make sure to enable Local to Scene on all of the Resource checkboxes! Having even one of the 3 Local to Scene checkboxes unchecked will make it show as purple in-game.

Grandro commented 1 week ago

Please note, that there is also #96816 which sets the NodePath of the ViewportTexture incorrectly when you instance a scene containing a Node that uses a ViewportTexture into another scene. So you have to set resource_local_to_scene on all materials that directly or indirectly use a ViewportTexture as described above, and if these materials are on a node that are part of an instanced scene, you also have to make them recursively unique, for them to become local to the new scene they are used in. So this is just a complete mess right now basically ^^'