mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.02k stars 35.33k forks source link

Feature suggestion: Support Maya's PBR material in FBXLoader #15927

Open looeee opened 5 years ago

looeee commented 5 years ago

PBR materials are exported to FBX from Maya using a proprietary extension ( Maya|xxxx).

A couple of these were added in #15844 which was a good start but doesn't take into account the fact that the Maya| prefix in FBX denotes that it's a PBR material, which should be used to create a MeshStandardMaterial.

According to this issue: https://github.com/assimp/assimp/issues/1504, this is a complete list of the materials that can be exported from Maya to FBX:

Material: 2967359479536, "Material::StingrayPBS2", "" {
        Version: 102
        ShadingModel: "unknown"
        MultiLayer: 0
        Properties70:  {
            P: "Maya", "Compound", "", ""
            P: "Maya|TypeId", "int", "Integer", "",1166017
            P: "Maya|TEX_global_diffuse_cube", "Vector3D", "Vector", "",0,0,0
            P: "Maya|TEX_global_specular_cube", "Vector3D", "Vector", "",0,0,0
            P: "Maya|TEX_brdf_lut", "Vector3D", "Vector", "",0,0,0
            P: "Maya|use_normal_map", "float", "", "",0
            P: "Maya|uv_offset", "Vector2D", "Vector2", "",0,0
            P: "Maya|uv_scale", "Vector2D", "Vector2", "",1,1
            P: "Maya|TEX_normal_map", "Vector3D", "Vector", "",0,0,0
            P: "Maya|use_color_map", "float", "", "",0
            P: "Maya|TEX_color_map", "Vector3D", "Vector", "",0,0,0
            P: "Maya|base_color", "Vector3D", "Vector", "",1,0,0
            P: "Maya|use_metallic_map", "float", "", "",0
            P: "Maya|TEX_metallic_map", "Vector3D", "Vector", "",0,0,0
            P: "Maya|metallic", "float", "", "",0
            P: "Maya|use_roughness_map", "float", "", "",0
            P: "Maya|TEX_roughness_map", "Vector3D", "Vector", "",0,0,0
            P: "Maya|roughness", "float", "", "",0.33
            P: "Maya|use_emissive_map", "float", "", "",0
            P: "Maya|TEX_emissive_map", "Vector3D", "Vector", "",0,0,0
            P: "Maya|emissive", "Vector3D", "Vector", "",0,0,0
            P: "Maya|emissive_intensity", "float", "", "",0
            P: "Maya|use_ao_map", "float", "", "",0
            P: "Maya|TEX_ao_map", "Vector3D", "Vector", "",0,0,0
        }
    }
    Material: 2967565876448, "Material::phong2", "" {
        Version: 102
        ShadingModel: "phong"
        MultiLayer: 0
        Properties70:  {
            P: "AmbientColor", "Color", "", "A",0,0,0
            P: "DiffuseColor", "Color", "", "A",1,0,0
            P: "DiffuseFactor", "Number", "", "A",0.800000011920929
            P: "TransparencyFactor", "Number", "", "A",1
            P: "SpecularColor", "Color", "", "A",0.5,0.5,0.5
            P: "ReflectionFactor", "Number", "", "A",0.5
            P: "Emissive", "Vector3D", "Vector", "",0,0,0
            P: "Ambient", "Vector3D", "Vector", "",0,0,0
            P: "Diffuse", "Vector3D", "Vector", "",0.800000011920929,0,0
            P: "Specular", "Vector3D", "Vector", "",0.5,0.5,0.5
            P: "Shininess", "double", "Number", "",20
            P: "Opacity", "double", "Number", "",1
            P: "Reflectivity", "double", "Number", "",0
        }
    }
    Material: 2967588203904, "Material::lambert2", "" {
        Version: 102
        ShadingModel: "lambert"
        MultiLayer: 0
        Properties70:  {
            P: "AmbientColor", "Color", "", "A",0,0,0
            P: "DiffuseColor", "Color", "", "A",1,0,0
            P: "DiffuseFactor", "Number", "", "A",0.800000011920929
            P: "TransparencyFactor", "Number", "", "A",1
            P: "Emissive", "Vector3D", "Vector", "",0,0,0
            P: "Ambient", "Vector3D", "Vector", "",0,0,0
            P: "Diffuse", "Vector3D", "Vector", "",0.800000011920929,0,0
            P: "Opacity", "double", "Number", "",1
        }
    }

Note: As far as I can see all PBR materials that are supported by the Maya FBX exporter use this extension, which is at least the Stingray and Arnold shaders.

I've come across a couple of mentions that other apps besides Maya may have also adopted the maya| extension for PBR materials, but I haven't verified this. However, 3D Max uses it's own proprietary extension, which should be trivial to add once we've set up Maya's extension. .

Adding support for this will require some refactoring of the material system in the FBXLoader, but should be fairly straightforward.

If nobody else takes this on, I'll get round to it... someday 😁 In the meantime I'm putting the information up here so that if somebody else needs this they it will be as easy as possible for them to implement.

b1skit commented 5 years ago

+1 for Maya PBR shader support

KurtMitchellGR commented 4 years ago

Is anyone working on this? I'm new to Three.js and really struggling with the GLTF pipeline (seems so complicated to get gltf from maya), is it possible to support the new Maya StandardSurface from Maya2020?

looeee commented 4 years ago

I think that this should be pretty easy to do, although a bit time consuming to verify that everything is correct.

There's three steps I would take to do this:

  1. verify that the list of Maya-> FBX materials that I put in my comment above is still correct in Maya 2020.
  2. Create a set FBX files that demonstrate the various materials and features we want to support (very simple, each file can just have a cube with the materials applied). Export each in ASCII and Binary formats to make testing easier.
  3. To add the materials to the loader, start here in the FBXLoader.parseMaterial function and add new material types beside Lambert and Phong. I would test for the presence of Clearcoat in the material and use that to decide whether to create MeshStandardMaterial or MeshPhysicalMaterial. Material creation is one of the simpler parts of the loader so it shouldn't be too hard.

I don't use Maya myself so I can't create the test files, however if someone else is interested in working on this I will support them.

KurtMitchellGR commented 4 years ago

I'm available for the next 5 hours to help you work on this (can help tomorrow also), tell me exactly what you want me to export and I'll send it over to you. As far as I'm aware, Lambert/Phong/PBS Stingray are still supported (but with complex pbr value translation to three), If we could add aiStandardSurface and standardSurface (arnold & maya) respectively that would be amazing (arnold shader is bundled in all the latest versions, and the maya standard surface is a new 2020 PBR shader.

For me personally, the ability the define a colour/roughness/metallic/normal/opacity/emissive/ao value in these shaders in Maya, and for them to translate directly into the three.js MeshStandardMaterial would be invaluable.

So yeah tell me exactly what you need and I'll send it over.

looeee commented 4 years ago

I'm not available to work on this on such short notice. But if you create a zip file with some cubes with completely default versions of those materials, and put it up here, that would be a good start for whoever wants to work on step 3.

EDIT: in case it's not clear, by 'support' I mean that I will help to verify some else's pull request. I don't have time (or interest, since I don't use Maya) to work on this feature myself.

KurtMitchellGR commented 4 years ago

Hi, that's understandable!

I've attached the test .fbx file, 5 cubes with the 3 standard supported materials and the 2 new commonly used PBR shaders. (I also think adding basic Vray/Redshift/Corona materials would be great also! but not necessary I guess)

threejs_materialupdate.zip

Thanks!