mrdoob / three.js

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

Distinguish generated materials from the ones coming from the model in loaders #26087

Closed kovacsv closed 1 year ago

kovacsv commented 1 year ago

Description

Most 3D model formats define the materials of the model. On the other hand there are situations where materials are not defined for some polygons. For example: "stl" doesn't define materials at all, it's possible to load an "obj" file without the "mtl" file, and so on.

In these cases most of the loaders use some kind of default material which differs from loader to loader. Sometimes it's white, sometimes it's purple, and who knows how many variations are out there.

From the end result it's impossible to tell whether a color is coming from the model or it's generated by the loader. This information can be useful if an application wants to provide recoloring when the model doesn't have material information.

Solution

Introduce a common user data to distinguish generated materials from the ones coming from the model. Add an isGeneratedByLoader (or something like that) boolean field to the user data of the generated material, so later it can be decided if it's coming from the model or generated by the loader.

Alternatives

Additional context

I would use this in Online 3D Viewer where you can set the material in settings if the model has no material. When using three.js loaders I can't implement this functionality since I can't tell if a material is coming from the model or it is generated by the loader.

kovacsv commented 1 year ago

I'm happy to do the implementation, I just wanted to check here if it makes sense. What do you think?

mrdoob commented 1 year ago

In these cases most of the loaders use some kind of default material which differs from loader to loader. Sometimes it's white, sometimes it's purple, and who knows how many variations are out there.

I think we first need some clarity on that statement...

  1. Which loaders make white materials?
  2. Which loaders make purple materials?
  3. We need to know how many variations are out there and how this change will solve those.
kovacsv commented 1 year ago

@mrdoob this proposal is not intended to reduce the number of default material variations. If all of them would be - let's say - white, I still wouldn't be able to tell if it's white because it was white in the model or because it's generated by the loader.

Having less variations would be great, but won't solve my use case. This is why is proposed the introduction of a new user data field.

On the other hand I'm happy to introduce a common default material in loaders, too, but what I really need is a method to distinguish the generated ones.

donmccurdy commented 1 year ago

Rather than modifying .userData or creating new APIs, perhaps we could adopt a naming convention for these materials? So applications could check for material.name === '__DEFAULT' or something like that.

Aside – the glTF format specifies what a default material should be, if omitted by the model, as defined here.

kovacsv commented 1 year ago

@donmccurdy this is fine by me, I'll open a PR with the change. We can also agree on a standard default material color if you wish. My proposal is simply white.

LeviPesin commented 1 year ago

Maybe the default materials can also do something like map: new Texture()? So, if the user have configured Texture.DEFAULT_IMAGE to be e.g. purple image, they will see it (a missing texture) on missing materials.

donmccurdy commented 1 year ago

Maybe the default materials can also do something like map: new Texture()?

I think I would prefer we didn't. Use of a default material does not imply that something is "missing", and it may be that the file intentionally contains only geometry. The purpose of the default texture may not be the same, and in any case the user can handle this as they prefer when the default material is identified.