godotengine / godot

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

Cannot bake lightmaps for procedurally generated ArrayMesh #76886

Open blackears opened 1 year ago

blackears commented 1 year ago

Godot version

v4.0.2.stable.official [7a0977ce2]

System information

Windows 10, Forward+

Issue description

I'm procedurally generating an ArrayMesh for a class I'm making that extends Node3D. This node creates an ArrayMesh and assigned it to the mesh of a MeshInstance3D. The ArrayMesh has UV2 coordinates defined for the lightmap. However, when I select the LightmapGI in my scene and try to start the bake, I get an error saying No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake Light' flag is on.'

I cannot find a Bake Light flag anywhere and my meshes have a UV2 channel. Why is the bake not working?

Steps to reproduce

Open the attached project. Select the LightmapGI node in the main.tscn project and select Bake Lightmaps from the editor toolbar. An error message will be produced saying there are no meshes to bake.

Minimal reproduction project

lightmap_runtime_node.zip

clayjohn commented 1 year ago

There are no Meshes in your SceneTree to bake in this MRP. What the LightmapGI node does is walk through the SceneTree and look for meshes that it can bake. Since you don't have any meshes in your scene until you run your script, there is nothing for the LightmapGI to bake. The meshes/MeshInstances that you want to bake in your LightmapGI need to be in the SceneTree at edit time in order to bake them at edit time. You can't bake MeshInstances at edit time that are not created until run time.

Here is what your SceneTree looks like, note the lack of MeshInstances: image

blackears commented 1 year ago

Well, I'm creating a tool that runs in the editor and lets users draw blocks to block out a scene. The blocks don't exist until the user draws them. Because this is all operating in an EditorPlugin, I'm forced to use script nodes since the editor plugin interface only lets you register scripts as types via EditorPlugin.add_custom_type(). As far as I can tell I can't register a scene in the same way. Is there a way for my editor addon to create bakeable blocks?

gongpha commented 1 year ago

I think the issue title can be misleading. The reason that made the lightmapper couldn't find the MeshInstances is that they were lacking the owner of the scene. But the title could be meaning procedural generating in run-time, which can work normally.

Ref : https://github.com/godotengine/godot/blob/72f7131be1be81e3b8c3d45732d55e5765b95dde/scene/3d/lightmap_gi.cpp#L413-L419

blackears commented 1 year ago

Setting the owner, though, will mean the MeshIntance3D will be saved in the *.tscn file rather than being generated in the _ready() function. Maybe I can just give them a standard name and then check to see if they already exist before generating a new one.

Calinou commented 1 year ago

This makes me think whether owner-less meshes should have light baked, since you can already use the bake mode properties in GeometryInstance3D to control whether light should be baked on it.

gaudecker commented 8 months ago

What are the downsides of baking ownerless meshes? I assume this limitation exists for a reason.

blackears commented 8 months ago

Well, it's just not possible. I'm not sure why they have the limitation, and it sounded like they might be able to just remove it from what they were saying, but as of now Godot requires all nodes you create in the editor by scripts to have the owner field set if you want baked lighting to work.

gaudecker commented 8 months ago

I apologize, I should've been more clear.

What I was asking was: what are the consequences of removing that ownership check from the code?

Calinou commented 8 months ago

I think the reason is that there's no way to persist UV2 in a way that preserves it across scene reloads. This makes it largely useless to bake lightmaps (since it can't be done at runtime in an exported project), at least unless you find a way to persist it yourself.

Feel free to try removing this check locally and see what happens :slightly_smiling_face:

blackears commented 8 months ago

@Calinou I'm actually generating my own UV2s, so I don't need the baking to do that. Is there a way to bake the lighting in this case?

Calinou commented 8 months ago

@Calinou I'm actually generating my own UV2s, so I don't need the baking to do that. Is there a way to bake the lighting in this case?

LightmapGI doesn't have its bake() method exposed, so no.