hubs-blender-exporter
hubs-blender-exporter copied to clipboard
Utility for lightmap preparation
Lightmaps are a pain to bake because you have to remember to always do the following:
- Select all the objects that should be light mapped
- Make sure the selected UV layer is correct for every mesh
- Make sure the lightmap image texture is active in the material graph
Miss any one of these steps and your bake will fail, probably silently and after a long time.
This PR adds a new Hubs 'Panel' to the Render Properties that has a button that finds all the MOZ_lightmap components and traverses the scene graph making sure everything is selected and active. It also does some strict error checking, so a positive result means you are ready to bake, but anything inconsistent (such as a missing image or missing UV layer) will throw an error.
I've tried to match the same style as the other Hubs panels, but the actual scene logic was a bit verbose so I put it into it's own file.
Blender doesn't seem to have a concept of "parents" for things like meshes, which doesn't make much sense to me, but we just use full search in those instances. Performance isn't an issue, but it does make the code a bit ugly.
Blender doesn't seem to have a concept of "parents" for things like meshes, which doesn't make much sense to me
This relationship is expressed in Objects
. Each Object
can have a "Data", things like Mesh
, Light
, and Camera
are all "Data" and can be referenced by multiple Objects.
Blender doesn't seem to have a concept of "parents" for things like meshes, which doesn't make much sense to me
This relationship is expressed in
Objects
. EachObject
can have a "Data", things likeMesh
,Light
, andCamera
are all "Data" and can be referenced by multiple Objects.
I was expecting some sort of parent property that would let me go up the hierarchy easily like we can with the HTML DOM. It might need to be a list of parents I guess, but I can't think of a good reason they didn't include it.
I forgot to make this PR draft originally.
In developing this script I discovered a complication in the Blender baking process. The behaviour appears to be that Blender starts with the selected objects and performs a bake on every materials that object uses, targeting the active image texture or just the first one if there isn't anything selected. This is why it's important to activate the right one before baking.
The consequence of this is that you can't have mixed-material objects where one is light mapped and another is not. This sounds like an obscure use case, but it happened in the first real Blender file I ran the script on. In this scene there was a spear with a wood shaft and a stone head. The stone material was also used by some large rocks in the scene that needed a lightmap. Usually this is best practice material sharing and lightmaping the tip of the spear isn't going to cause any harm (a few lost pixels in the lightmap), but because that same object uses the wood material the bake will end up corrupting one of the input textures.
I've added a sanity check when the script runs to warn the user in this mixed-material scenario.
This Blender project demonstrates the problems of mixed materials and baking irrespective of this add-on.
I've added some functionality to cope with the mixed material situation that allows you to add dummy image textures (based on a suggestion by Jim). This works well, but obviously complicates the plug-in a bit, but to some extent it's just reflecting the complexities of Blender baking. By adding things things to the scene file it does more than just select things, which is a shame because I prefer add-ons that "first do no harm". To try and counter this I included a Remove all button that tidies up the mess it makes.
Instructions
Basic Use
This Blender file contains a scene with a single lightmapped material that is shared by two meshes and two more materials that are applied to two different meshes:

Pressing the Select all lightmap elements for baking button selects:
- the objects with lightmapped materials (this tells Bake what to process)
- the lightmap UV set (read from the material graph)
- the faces within the mesh of those objects that are assigned the lightmapped material (ready for UV packing)
- the lightmap image texture from the material itself (this tells Bake what image to write to)
Technically things are made "active" rather than "selected", but this is a Blender API distinction that doesn't need concern the user.
In this state the UV's are in ready to be unwrapped for lightmapping either though the built in "Lightmap pack" (which isn't great) or whatever method the user sees fit.

Once the UVs are set they won't need to be changed unless the models change. Then the user only needs to select the proper baking method (typically Diffuse with Direct and Indirect contributions) and press the Bake button.
Multiple Lightmaps
It's also possible to have multiple lightmaps defined across multiple objects. We have found this setup useful where either a single texture doesn't provide enough pixels or you want to split indoor and outdoor lightmaps to allow for finer grained scaling.
This Blender file contains a scene where one material uses Lightmap1
and two materials share Lightmap2
.

When multiple lightmaps are found, the panel lists them independently for selection to allow for UV packing. The main button selects all the lightmapped materials as before so all the lightmap images can be baked at once.
Cross-Material Lightmaps
Object meshes can have different materials assigned to different faces as can be seen in this Blender file, where the top faces of two of the cubes share the lightmapped material:

Pressing the Select all lightmap elements for baking button will select all the objects in the scene as before, but it will also throw an error message because if you baked at this point the ColorTexture
material would be corrupted as Blender looks for the first image texture it can find if none is active. Note that the Red
material is safe because it has no image textures; Blender will inform the user about this during baking, but it won't cause any problems.
The new panel includes a Decoy Textures section with an Add to Selected button. When you press this button it will add an image texture with the label HUBS_DECOY_IMAGE_TEXTURE to any material that is deemed "at risk" - i.e. is selected, has an image texture, but has no lightmap target. Pressing Remove All will do just that to all materials whether the objects are selected or not.
This situation is actually quite common in production scenes. One real-world example is where we had a spear mesh with two materials: wood and stone. The stone material was already being used for the interior of a cave and had a lightmap, but the wood material did not. Baking without dummy textures corrupts the wood image textures.
@rawnsley Thanks for this. I think this would be a great first Hubs add-on tool to have. I feel the baking pain and having something that saves you a few clicks and headaches is always welcome. My initial obvious comment is that we would need to update this to the latest add architecture. It shouldn't be much effort as this is quite independent element of the plugin so it should just be a matter of moving things around.
We currently have a components module for all hubs component related. We can probably create a tools
module in the add-on root to host this and future tools and bundle all the PR files inside its own render
module under tools.
Other than that and pending a deeper code review I think we can start with the current UI proposal. Maybe we could put the lightmapping UI inside a Ligthmap
box (similarly to what we do in the components list) to separate it from future tools UI but we can do that later when we have more tools.
Regarding the decoy textures. I wasn't able to reproduce the texture corruption using your multi-material example file above and Blender 3.1.2. Maybe this is something that has been fixed in the latest Blender versions?
Let us know if you are willing to update this branch yourself or you prefer us fork and do it ourselves.
@keianhzo Thanks for the feedback. Agreed on all of that - I'll take a look at refactoring my branch to eliminate the conflicts and confirm if the decoy textures are still required. It will be a good opportunity to familiarise myself with all of the good work you've been doing recently.
Just to be clear: are you thinking of keeping non-core tools like this in a new GitHub repository or just keeping them in a tools folder at the root of this repository?
I mean in addons\io_hubs_addon\tools\render
. I think they will be useful as part of the add-on itself. The render
panel where you have placed it seems like a good initial location to me.
@keianhzo I've (finally) got around to pulling in the current master branch. I've retested on Blender 3.6 and this tool is working as before.
I can confirm that texture corruption is still a problem in the "Cross-Material Lightmaps" scenario outlined above. Without using this tool: if you select all the objects in the scene and start a bake, the image for the ColorTexture material is overwritten erroneously.