facebookincubator / FBX2glTF

A command-line tool for the conversion of 3D model assets on the FBX file format to the glTF file format.
Other
2.1k stars 332 forks source link

Support for 3ds max DirectX Shader Interactive (Stingray PBS) exported FBX #156

Open EugenioMiolo opened 5 years ago

EugenioMiolo commented 5 years ago

Looks like only Maya's Stingray PBS material is supported by the FBX2glTF converter, while the 3dsmax DirectX shader in Interactive mode (it's the Stingray material) is not. So if a material in 3dsmax is PBR ready, you can't properly convert to glTF since we are stuck with 3dsmax Standard material which is a very old, non PBR material.

So please, add support for an FBX exported from 3dsmax with the DirectX shader in Interactive mode. Here's a screenshot of how this shader look like in 3dsmax:

image

zellski commented 5 years ago

Hey @EugenioMiolo,

I'd consider adding this material, but realistically it's not going to happen anytime soon –– unless you can add it yourself, or find a willing engineer contribute a solution. I'm out of spare cycles for the time being. That said, I did add support for 3dsmax' "Physical Material" some months, and you should be able to give that a whirl either by compiling this tool from source, or waiting for a 0.9.6. release.

Another issue is that I don't have a 3dsmax subscription, and so would depend on someone else to supply me with a couple of example FBX files that make use of this material.

EugenioMiolo commented 5 years ago

Thanks a lot for the answer @zellski.

If Physical Material is supported that would be great (and no need for DirectX shader support)! Though it's strange because I've compiled the tool and tested with physical material, but it didn't work.

Here's my test file and a screenshot of how the material looks like in 3dsmax: (https://github.com/facebookincubator/FBX2glTF/files/2755125/Physical_Material.zip) image [Physical_Material.zip]

Here's FBX2glTF converter version I'm using: image

EugenioMiolo commented 5 years ago

Any chance to get some help on this one?

Thanks

zellski commented 5 years ago

@EugenioMiolo Yeah -- I will test against your provided FBX file later today!

zellski commented 5 years ago

Hah, well, that was embarrassing. I'd made some very questionable commit back in August that added both old and new versions of the materials classes, and I guess I never resolved all that. Now that I've cleaned it up a bit, the Physical Materials code is actually running and correctly outputting some better PBR factors to the generated glTF.

Unfortunately, I now see my Physical Materials code is extremely basic. It doesn't even handle converting the bump maps (which appears to be what this shader uses) to normal maps (which is what glTF requires).

But it's better than nothing, and perhaps it'll interest someone else in adding more support. :)

Feel free to recompile from master now if you want to give it a whirl yourself. Otherwise, this contains the GLB generated from your FBX: Physical_Material.zip

EugenioMiolo commented 5 years ago

Hi there @zellski,

Thank you for taking a look at this. Looking at your file, it seems there's no texture with it.

I've recompiled the converter from master but still can't get Physical Material to convert. The converter now kinda sees the Physical Material because it gives the message below, but the output file has no textures. image

I know you are kinda tired about this subject, but IMO it's important since, from 3dsmax, there's no easy way to convert a PBR ready material to glTF with this converter. Making the most basic scenario a complication (a simple material with mapped color, metallic, roughness and normal).

My suggestion is another approach though (similar to XCode usdz_converter). Instead of trying to convert the Physical Material (it should be supported at some point), simply add flags when using the command line tool, the user pass the scene node to apply the material and the path for the maps supported by the glTF PBR shader. The converter builds the glTF PBR material for that node/nodes from scratch. It may not be as simple and straightforward as just converting a supported material, but would be very useful already, and app agnostic (which is very nice on itself). Could also have flags to specify if the material is opaque/transparent.

Example of how I imagine this working: 3D scene in DCC package like Maya/3dsmax:

warrior.fbx:
   "Helmet"
   "Body"

The command line would look like:

c:\tmp\FBX2glTF warrior.fbx 
-node Helmet 
    -base_color c:\tmp\helmet_base_color.jpg 
    -metallic_roughness c:\tmp\helmet_metallic_roughness.jpg 
    -normal c:\tmp\helmet_normal.jpg 
-node Body 
    -base_color c:\tmp\body_base_color.jpg 
    -metallic_roughness c:\tmp\body_metallic_roughness.jpg 
    -normal c:\tmp\body_normal.jpg

Hope this makes sense. Would be too hard to do something like this?

zellski commented 5 years ago

Hey @EugenioMiolo --

I'm not tired of the subject at all -- if anything I'm embarrassed that I got this so wrong so many times. :-) I'm not that keen on a command-line based solution like the one you suggest... I might accept a diff for it, but beware that it's quite a lot of fairy tedious work to do that much command line parsing, file system lookups, sanity checking, error reporting, bla bla bla. And in the end, it's just such an extremely "power user" oriented feature –– if I were to take a step in that direction, I would want to do the full visual deal where you drag a FBX into a web browser, get an instant preview of the conversion, and you are able to click to replace / populate different texture types from the local file system. THAT would be truly useful.

However, I think I did finally fix physical material import. Is this more like what you were expecting? It has a base color and metallic/roughness. I still need to convert bumpmap to normal map though.

image

zellski commented 5 years ago

Fixed in https://github.com/facebookincubator/FBX2glTF/commit/d0883136d34f8804bcab7535be287d0e17c5bda0.

EugenioMiolo commented 5 years ago

Hi there @zellski! It's definitely much better to have proper support of physical material, makes everything a lot more straightforward. I thought a command line approach would be somewhat easier to implement.

Yes, the cube looks like what it should be! But keep in mind it's not a real asset, it's just a debug object :). I'm rather curious about what you mean with "converting bump maps to normal maps"? Do you plan to do some fancy math to derive normals from a bump map? What if I'm already using a normal map? In max there's a map called "normal bump" which is plugged into bump mapping. In that case, no conversion should be made an you would simply use this map as normal map in the gltf material.

One last thing, can I control if a material is flagged as transparent or opaque during the conversion?

I will give it a try on this latest version ASAP.

Kind regards, Eugenio

zellski commented 5 years ago

Hey @EugenioMiolo! I'm not sure what to think about the 3dsMax "Normal Bump" map.

It sounds like it's primarily designed to accept a normal map, but to export to either bump or displacement? In any case, once it's applied to a Physical Material, it looks like it'll be either in the form of a bump- or a displacement map, but glTF always expects a normal map, so yes –– some fancy math will be required.

The math looks pretty straight-forward, honestly. I already have supported from generating one texture from some set of other textures on a pixel-by-pixel basis... I just have to expand it to a real filter kernel, so that some p(x, y) in the generated texture can depend on the entire neighbourhood of (x, y).

I don't suppose you have, or know, of any significant asset that uses non-trivial amounts of Physical Material? The lack of test models has been the greatest hurdle in all this.

EugenioMiolo commented 5 years ago

Sorry for the late reply @zellski . I've been busy these days...

The Normal Bump map in max is just the way max supports normal mapping. The bump slot inside the Normal Bump map is for mixing a grayscale bump image with the normal map.

My suggestion is if there's a Normal Bump map in the bump slot of the material, use whatever texture is inside the Normal slot inside Normal Bump map. At the very least to have a straight way to get a normal map exported from max to gltf.

Because if even if you convert bump maps to normals, that would still leave a gap in workflow. E.g.: Imagine you have to build assets that you know are going to be exported to gltf later on. So you try to keep everything as compatible as possible. Since gltf only works with normal maps, it makes sense to only use normal maps on your models. However, you can't export these correctly since the converter expects grayscale bump images. Then we would need to convert normal maps into grayscale bump maps? That would be odd.

That's my main concern atm. I think at least a way to make the converter know that my bump is a normal map is needed (maybe just a --normal flag for that).

This is how our assets are, the converter just needs to put my maps into the respective places in the gltf material, nothing fancy is needed in our case (and we are almost there 👍, just missing normal maps :P ). I think it worth mentioning that we are quite likely to be the ones who make the heaviest use of your tool if it works for us, because it will be part of our pipeline, and we generate thousands of assets every month (https://cora.creativedrive.com/).

And last but not least, is it too complicated for the converter to just generate a binary from a gltf as input?

Offtopic: Just out of curiosity, are you using C++ to make the converter? Any particular reason for that?

Kind regards, Eugenio

zellski commented 5 years ago

Hey @EugenioMiolo, thanks for the response. No apologies needed; trust me, I understand. I juggle a lot of tasks, and FBX2glTF is primarily a hobby endeavour for me.

It's very exciting to hear that you're considering using the tool for a high-throughput pipeline. That's pretty much the use case I am interested in, myself. Let's try to work together to satisfy your needs, although again –– if you need to see faster progress, the best thing you can do is allocate some time for an engineer to help out with some PRs to this repository. I have so little time available.

Detailed replies in reverse order...

Just out of curiosity, are you using C++ to make the converter? Any particular reason for that?

Yes Primarily, because we need to link against Autodesk's FBX SDK. However, there are also quite a few operations that are genuinely time consuming (e.g. animation baking) and would do poorly in slower languages. Finally, while I might prefer other languages, the original version of the tool were written by folks who are extremely comfortable in a C++ environment.

And last but not least, is it too complicated for the converter to just generate a binary from a gltf as input?

It's not so much that it's complicated, it's more that what you propose is practically the definition of feature bloat. This tool does one thing: converts FBX files to glTF files. The functionality you describe is pretty much exactly what gltf-pipeline exists to do. Have you looked into that?

My suggestion is if there's a Normal Bump map in the bump slot of the material, use whatever texture is inside the Normal slot inside Normal Bump map. At the very least to have a straight way to get a normal map exported from max to gltf.

The problem is that all we have to go on is what's in the FBX file, and unless I'm missing something, there's no way to distinguish a "Normal Bump" texture from a "Bump" texture at this point. All I have is a "3dsMax|Parameters|bump_map" property, which points to a texture. I have to assume that the Physical Material exporter actually takes a "Normal Bump" map and converts it to a grayscale bump map for export.

From your point of view, I understand that it's ridiculous to convert a normal map to a bump map, export that to FBX, and then have this converter translate it back to normal map (each time introducing slight numerical losses & the possibility of bugs)... but I'm not sure what the best workaround is. A --physical-material-bump-maps-are-actually-normal-maps flag would be a last resort, but I'm willing to consider it –– before we do so, though, are you sure it's possible for you to export an FBX using Physical Material that actually exports an un-translated Normal map?

To investigate further, could you put together a version of that cube that has a real Bump map, and also another version that has a Normal Bump map? Ideally also export the FBX as ASCII; it makes it a lot easier to investigate the contents.