Skip to content
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

Exporting Alternate Materials #231

Closed
robert-nash opened this issue Jan 14, 2019 · 26 comments
Closed

Exporting Alternate Materials #231

robert-nash opened this issue Jan 14, 2019 · 26 comments
Labels
enhancement New feature or request exporter This involves or affects the export process Material

Comments

@robert-nash
Copy link

I know that this is quite a broad workflow issue which is not necessarily specific to this addon but I wonder if the addon might be able to facilitate this.

I am exporting a model from Blender to Babylon.JS as outlined [here](https://blender.stackexchange.com/questions/128741/exporting-alternate-materials-to-gltf) and I want to be able to have alternative materials for a mesh such that the user can choose between different materials. At the minute it seems to be only possible to export materials which are assigned to a material and then only from the first material slot.

I wonder if there is anyway that this addon could export materials which aren't assigned to a mesh in Blender?

@julienduroure julienduroure added enhancement New feature or request exporter This involves or affects the export process labels Jan 16, 2019
@UX3D-nopper UX3D-nopper added this to the Community milestone Jan 17, 2019
@julienduroure julienduroure removed this from the Maintenance & Community milestone Sep 26, 2019
@maloguertin
Copy link

maloguertin commented Feb 19, 2020

Also interested in this. Also I'm pretty sure the old exporter used to export the alternate materials.

@donmccurdy
Copy link
Contributor

donmccurdy commented Feb 27, 2020

Is what you're describing here basically that the exporter would include all materials available in the scene when exporting to glTF, even if some of those materials aren't used by any mesh? So they'd be unattached, but engines could access them and use them as needed?

Note that there wouldn't be any sense of exactly which mesh the materials are alternates for. It's just a bag of materials, and the engine can use mesh and material name (and custom code) to assign them properly.

If that's all OK, this seems like a reasonable thing to have available as an option, but probably disabled by default. I think the same logic could apply to textures — users might create a lightmap or other texture that glTF doesn't support, and just want to bundle it, so their runtime can do something with it.

A more formal proposal for alternate materials has been made on the glTF repository, but I'm not sure whether that fits well into this Blender exporter, or whether it's near enough completion to implement.

@maloguertin
Copy link

Is what you're describing here basically that the exporter would include all materials available in the scene when exporting to glTF, even if some of those materials aren't used by any mesh? So they'd be unattached, but engines could access them and use them as needed?

Note that there wouldn't be any sense of exactly which mesh the materials are alternates for. It's just a bag of materials, and the engine can use mesh and material name (and custom code) to assign them properly.

If that's all OK, this seems like a reasonable thing to have available as an option, but probably disabled by default. I think the same logic could apply to textures — users might create a lightmap or other texture that glTF doesn't support, and just want to bundle it, so their runtime can do something with it.

A more formal proposal for alternate materials has been made on the glTF repository, but I'm not sure whether that fits well into this Blender exporter, or whether it's near enough completion to implement.

I can't talk for @robert-nash, but that would work perfectly for me, as long as the names are kept like for other materials it's easy to reassign them.

@feiss
Copy link

feiss commented Apr 4, 2020

Yeah, I think this is very interesting and can be very useful

@StidOfficial
Copy link

I am interresting by this feature for select materials avalaible in GLTF with ThreeJS. It's very bloken with only active materials

@StidOfficial
Copy link

With this

First implementation of KHR_materials_variants :

--- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
+++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
@@ -15,7 +15,7 @@
 import bpy
 from typing import List, Optional, Tuple
 
-from .gltf2_blender_export_keys import NORMALS, MORPH_NORMAL, TANGENTS, MORPH_TANGENT, MORPH
+from .gltf2_blender_export_keys import NORMALS, MORPH_NORMAL, TANGENTS, MORPH_TANGENT, MORPH, UNUSED_MATERIALS
 
 from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
 from io_scene_gltf2.blender.exp import gltf2_blender_extract
@@ -48,7 +48,7 @@ def gather_primitives(
     primitives = []
 
     blender_primitives = __gather_cache_primitives(blender_mesh, library, blender_object,
-        vertex_groups, modifiers, export_settings)
+        vertex_groups, modifiers, material_names, export_settings)
 
     for internal_primitive in blender_primitives:
         material_idx = internal_primitive['material']
@@ -64,10 +64,9 @@ def gather_primitives(
             # no material at that index
             pass
 
-
         primitive = gltf2_io.MeshPrimitive(
             attributes=internal_primitive['attributes'],
-            extensions=None,
+            extensions=internal_primitive['extensions'],
             extras=None,
             indices=internal_primitive['indices'],
             material=material,
@@ -85,6 +84,7 @@ def __gather_cache_primitives(
         blender_object: Optional[bpy.types.Object],
         vertex_groups: Optional[bpy.types.VertexGroups],
         modifiers: Optional[bpy.types.ObjectModifiers],
+        material_names: Tuple[str],
         export_settings
 ) -> List[dict]:
     """
@@ -98,6 +98,7 @@ def __gather_cache_primitives(
     for internal_primitive in blender_primitives:
         primitive = {
             "attributes": __gather_attributes(internal_primitive, blender_mesh, modifiers, export_settings),
+            "extensions": __gather_extensions(internal_primitive, blender_mesh, modifiers, material_names, export_settings),
             "indices": __gather_indices(internal_primitive, blender_mesh, modifiers, export_settings),
             "material": internal_primitive['material'],
             "targets": __gather_targets(internal_primitive, blender_mesh, modifiers, export_settings)
@@ -140,6 +141,35 @@ def __gather_indices(blender_primitive, blender_mesh, modifiers, export_settings
 def __gather_attributes(blender_primitive, blender_mesh, modifiers, export_settings):
     return gltf2_blender_gather_primitive_attributes.gather_primitive_attributes(blender_primitive, export_settings)
 
+def __gather_extensions(blender_primitive, blender_mesh, modifiers, material_names, export_settings):
+    def get_material_id(material_name):
+        for idx, _material in enumerate(bpy.data.materials):
+            if _material.name == material_name:
+                return idx - 1 # Skip "Dots Stroke" material
+
+        return None
+
+    extensions = {}
+
+    mapping = []
+    if export_settings[UNUSED_MATERIALS]:
+        for material_name in material_names:
+            mapping.append({
+                "tags": [ material_name ],
+                "material": get_material_id(material_name)
+            })
+
+    # If any extensions is set
+    if not mapping:
+        return None
+
+    if mapping:
+        if "KHR_materials_variants" not in extensions:
+            extensions["KHR_materials_variants"] = {}
+
+        extensions["KHR_materials_variants"]["mapping"] = mapping
+
+    return extensions
 
 def __gather_targets(blender_primitive, blender_mesh, modifiers, export_settings):
     if export_settings[MORPH]:

@donmccurdy
Copy link
Contributor

I'm not sure if we should export KHR_materials_variants based on unused materials, or start first with just the approach of #1080... is that stretching the purpose of Blender's material slots a bit?

Importing glTF variants to slots seems harmless though.

@StidOfficial
Copy link

Yes is based on materials slots (attached to the mesh).

@takahirox
Copy link

takahirox commented Feb 12, 2021

Hi, I'm interested in letting Blender support glTF KHR_materials_variants extension and found this thread.

Based on @StidOfficial's work I'm working on the trial of the glTF KHR_materials_variants import/export support. I'm very new to Blender but using unused materials in slots for KHR_materials_variants looks one of the good approaches.

A problem with this approach (or even other approaches) may be how variant names and grouping should be, like mapping ("variantName0" - MaterialA for MeshA and MaterialB for MeshB, "variantName1" - MaterialC for MeshA and MaterialD for for MeshB).

Does Blender have a core feature representing such grouping?

Update: I found that the slots can be ordered and the same material can be assigned to multiple slots. So slots also can be used as variant group, like slot0 for variant group0, slot1 for variant group1... (although user still needs to somehow provide variant names). I'm not sure if it's a good design but it doesn't require the extension specific UI/properties so much.

@takahirox
Copy link

Do you know if it is possible to assign a different name to a material slot from an assigned material? I thought material slot name can be used for variant name and variant material combination.

But MaterialSlot.name seems read-only. And updating MaterialSlot.material.name seems to have an effect to MaterialSlot.name, MaterialSlot.name will be the same as the MaterialSlot.material.name.

@emackey
Copy link
Member

emackey commented Feb 18, 2021

@takahirox I'm interested in a solution here too, but I don't know if exporting material slots in this way is workable. The material slots are already needed for meshes that have more than one material applied. During glTF export, the glTF meshes contain multiple primitives, one per material.

I suppose there could be an export configuration switch, to enable KHR_material_variants using material slots, but that would come at the expense of the ability to assign multiple materials to a single mesh. Each mesh in the file would need to contain a single material, with the slots used to offer variants. But this is well outside the normal usage pattern for Blender, so it might not be intuitive for people who are accustomed to the normal use of those slots.

I'm not actually sure what the right solution is here. Blender doesn't really have a matching concept of material variants.

@takahirox
Copy link

takahirox commented Feb 19, 2021

Hi @emackey, thanks for the comment.

Yeah, I studied Blender and started to think that the Material slots approach may not be intuitive especially to the existing blender users, too.

But I couldn't come up with better ideas so far. And I know there are users who want to import/export glTF file including KHR_materials_variants extension with Blender.

Some options for export in my mind so far are

  1. Add "Material slots for KHR_materials_variants" option which is disabled by default. The option may break normal Material slots usage so we request users to know the limitation for turning it on.

  2. Merge Export: All available materials #1080 for exporting unused material slots. And users add KHR_materials_variants extension with something external post-processing tools.

  3. Add extra UI and data structure for variants to Blender. It may be ideal for KHR_materials_variants but I'm not sure if adding them is under the glTF-Blender-IO policy/responsibility.

Regarding import, importing it into Material slots may be harmless as Don mentioned.

@robertlong
Copy link

robertlong commented Feb 24, 2021

Personally I'd go with option 3. We have a similar situation in the Hubs Blender Exporter where we allow you to specify alternate materials for a given "kit piece". We have an additional UI which allows you to pick the alternate materials for a given node:

image

I know that something like this wouldn't ship with Blender and probably couldn't be included in glTF-Blender-IO, but I think glTF extensions such as KHR_materials_variants start to define behavior that is outside the scope of what Blender should be expected to cover with its existing UI concepts. We should be able to explicitly define the material variants in Blender, not reuse the concept of unused Material Slots.

Is it possible that this extension, and others that would be better off with additional UI, be covered by a companion addon that includes support for additional extensions? In this way we can point advanced users of glTF to a "glTF-Blender-IO-extras" addon which can start to push the possibilities of the Blender glTF exporter forward? Both in UX and capabilities.

@emackey
Copy link
Member

emackey commented Feb 24, 2021

@robertlong That's a good idea, I think a separate KHR_materials_variants add-on working as a companion to this one could be really effective.

I'm less sure about a generic "glTF-Blender-IO-extras" addon, it sounds like that could become unfocused and suffer feature-creep. So I think an addon targeted to the specific extension would be better. I'm not sure who would write it or fund its development, though.

@takahirox
Copy link

I'm not sure who would write it or fund its development, though.

I'm willing to do it.

@emackey
Copy link
Member

emackey commented Feb 24, 2021

@takahirox Awesome! If you haven't already, take a look at the example glTF extension addon in this repo, for some idea how a 3rd-party addon can extend glTF export. The Mozilla Hubs addon (linked above) is also doing this I believe.

@takahirox
Copy link

takahirox commented Mar 7, 2021

@emackey

Thanks for the advices. Finally the prototype started to work...

As I commented #1009 (comment), I need the abilities to add extensions to the root glTF object (and access the entire glTF object). I added a workaround hack to my addon so far but I would be pleased if you or other members commented on that thread.

And question, does glTF-Blender-IO also have user extension hook mechanism even for importing glTF?

@emackey
Copy link
Member

emackey commented Mar 8, 2021

@takahirox Are you on the Hubs team too? Sorry about sending you a link to your own project's source...

Take a look at what Julian just submitted: #1347

And I don't think there's any import support... @jjcasmar Any ideas about hooking into the importer?

@jjcasmar
Copy link
Contributor

jjcasmar commented Mar 8, 2021

I haven't thought anything about hooking the importer nor I haven't found any interest for it, since I can save my scenes directly in blend format.

If the idea is to be able to share between different 3D software, like having a scene in Maya, export to gltf2 and import into blender, I think there are more suitable format.

@takahirox what is not working about adding root gltf objects? iirc, I have developed an addon which adds a tag system to gltf, creating tags in the root object and referencing them on the addons.

@julienduroure
Copy link
Collaborator

I think we can now close this ticket, as material variants extension is now part of this addon (in Blender 3.3)

@son208
Copy link

son208 commented Oct 21, 2022

Hi ! i have installed the KHR-materials variants addon into the blender, i tried exporting the glb file but there are no variants installed in it! How to fix that?
image

@julienduroure
Copy link
Collaborator

Hello,
You should propbably asked directly in @takahirox repository https://github.com/takahirox/glTF-Blender-IO-materials-variants

As noted here, takahirox/glTF-Blender-IO-materials-variants#20 this addon is no more really useful, as the glTF-Blender-IO addon is now fully compatible with Material Variant since Blender 3.2

You should have a look on documentation for more info : https://docs.blender.org/manual/en/latest/addons/import_export/scene_gltf2.html#gltf-variants

@son208
Copy link

son208 commented Oct 21, 2022

How to display it in the toolbox like document? And how to install it in the glb file export ? I am using blender 3.3 . thank you
1

@julienduroure
Copy link
Collaborator

As specified in documentation:

For a full Variants experience, you have to enable UI in Add-on preferences

I will add a screenshot in documentation to help people finding addon preferences

image

@son208
Copy link

son208 commented Oct 21, 2022

Thank so much ! you save a lot off my time !

@son208
Copy link

son208 commented Oct 21, 2022

Hey bro ! Currently I have 2 materials attached to 2 separate objects, is there a way to create 2 more of those materials and share 1 variant? If not, I think I will combine 2 objects and 2 materials and assign to each area. Do you find it feasible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request exporter This involves or affects the export process Material
Projects
None yet
Development

No branches or pull requests