-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Utility for lightmap preparation #48
base: master
Are you sure you want to change the base?
Conversation
This relationship is expressed in |
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. |
…pt to stop them being baked (it doesn't work for reasons unknown)
…hey will contribute to the bake if their parent object is selected
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. |
README instructions for uploading the GLB file
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. InstructionsBasic UseThis 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:
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 LightmapsIt'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 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 LightmapsObject 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 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 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 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 |
# Conflicts: # operators.py # panels.py
@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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rawnsley Sorry it took me so long to review, thank you very much for this! Overall this looks really good and I think it'll be of great use to people. The error checking is great! There are a couple things that I would like to discuss and/or I think could use a few tweaks, though.
- I noticed that there isn't any support for allowing a mapping node between the UV map and the image texture. I don't think support for this is needed, but thought I should mention it just to double check with you.
- Why are the light map faces being selected? It seems like this tool is mainly for baking once everything has been set up?
- Rather than trying to force everything into object mode, I think it would be better to use the poll on the operator to limit it to only run when in object mode.
- It looks like the selection and hidden status for all faces of all objects (regardless of whether they are light mapped or not) is being modified with little to no warning to the user. This should be limited to only objects with light maps on them.
- I think materials with 0 users should be skipped.
object
is a reserved keyword in Python (as much as anything is reserved in Python), so we've been trying to stay away from it,ob
orobj
has predominantly been used instead.- Blender supports materials being linked to Objects as well as to Meshes and this appears to export to glTF (although it looks like they store them on meshes in the glTF file). If you do something like the following for
selectUVMaps
instead of looping through the meshes and callingselectObjectFromMesh
, it should account for objects and be a bit faster (I think):
for ob in bpy.context.scene.objects:
if ob.type == "MESH":
for materialSlot in ob.material_slots:
if materialSlot.material:
if materialSlot.material.name == material.name:
ob.hide_set(False)
ob.select_set(True)
mesh = ob.data
etc.
for materialSlot in object.material_slots: | ||
material = materialSlot.material |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A material slot isn't guaranteed to have a material in it, so an if material
check is needed here.
Lightmaps are a pain to bake because you have to remember to always do the following:
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.