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

GLTFLoader: Explicitly clone ShaderMaterial properties. #12274

Merged
merged 2 commits into from
Sep 28, 2017

Conversation

donmccurdy
Copy link
Collaborator

Fixes #donmccurdy/three-gltf-viewer#42 (thanks @emackey!).

The spec/gloss ShaderMaterial is pretty fragile. 😕 Maybe we will want to revisit the idea of having MeshSGStandardMaterial at some point?

@donmccurdy
Copy link
Collaborator Author

/cc @takahirox

@takahirox
Copy link
Collaborator

Just curious to know if ShaderMaterial can be cloned correctly, we don't need explicitly clone ShaderMaterial properties?
I'd like to know the root issue.

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Sep 25, 2017

The cause of the linked bug is that material.map was not copied when cloning a shader material.

ShaderMaterial does the right thing, copying everything it knows about and invoking Material.copy(). But the Material class doesn't know about all of the MeshStandardMaterial properties we've added to the ShaderMaterial to support spec/gloss. So we have to explicitly clone all the things ShaderMaterial doesn't know about, when in an ideal world everything that's not unique to spec/gloss would be inherited instead.

@mrdoob mrdoob requested a review from takahirox September 25, 2017 05:33
@takahirox
Copy link
Collaborator

Hm, so having MeshSGStandardMaterial would be another option?

@takahirox
Copy link
Collaborator

IMO, this change is good so far but I'd like to add comments into the code why we need Explicitly clone ShaderMaterial properties.

And we'll also should try to fix ShaderMaterial.copy() issue and then revert once we've done.

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Sep 25, 2017

Hm, so having MeshSGStandardMaterial would be another option?

Yeah. The current status of that is probably @mrdoob's comment here, that we would wait to see if people use the workflow. I don't really expect people to create spec/gloss materials manually, but importing models that use the workflow has a bit of traction. In this case, the Minecraft exporter creates spec/gloss materials (why it does that, I don't know...).

So IMO the SG workflow is not something most users need to worry about when creating materials programmatically, but ideally it should work reliably when importing models. 😕

And we'll also should try to fix ShaderMaterial.copy() issue and then revert once we've done.

Not sure I understand — ShaderMaterial.copy() is working as intended, as far as I can tell. It just doesn't know about all these properties we've added ourselves, and therefore can't clone them.

@takahirox
Copy link
Collaborator

The problem I'm worrying is ShaderMaterial.copy() of SG material still doesn't work even if we merge this change.

If users want to copy of SG material in their user code, they need to be aware of that they need to explicitly clone properties instead of calling .copy(). This's very confusing.

So I wondered if we can enable ShaderMaterial.copy() to copy properties that users/we add. (But adding special properties to ShaderMaterial would be out of Three.js/ShaderMaterial manner?)

In my mind, I have three options.

  1. Support MeshSGStandardMaterial in Three.js core. It works fine but we need to reconsider MeshPhongMaterial.
  2. Enable ShaderMaterial.copy() to copy properties added by users/us. But this'd be out of Three.js manner.
  3. Declare MeshSGStandardMaterial in GLTFLoader.

I prefer 3. so far if it won't have any problems. Probably inheriting ShaderMaterial and overrides .copy() (and .clone()?) would be the easiest way. (Inheriting MeshStandardMaterial would be another option?)

@donmccurdy
Copy link
Collaborator Author

Even if we do (2) or (3), it will still not be possible to clone a THREE.ShaderMaterial created from a glTF model. In addition to copying properties, we need for the mesh.onBeforeRender callback of the material's mesh to refresh the material's uniforms, and ShaderMaterial.copy() can't do that.

This PR just corrects things so that at least the model renders correctly in the first place — cloning still does not work.

@takahirox
Copy link
Collaborator

OK, this change would be a good workaround if we add the comment why we need "Explicitly clone ShaderMaterial properties" into the code.

And let's keep discussing how to solve the root issue.

@donmccurdy donmccurdy force-pushed the feat-gltf-clone-shader-materials branch from c33ba19 to f51e228 Compare September 26, 2017 03:02
@donmccurdy
Copy link
Collaborator Author

OK, this change would be a good workaround if we add the comment why we need "Explicitly clone ShaderMaterial properties" into the code.

Sounds good — done.

@mrdoob mrdoob merged commit ca123ce into mrdoob:dev Sep 28, 2017
@mrdoob
Copy link
Owner

mrdoob commented Sep 28, 2017

Thanks guys!

@donmccurdy donmccurdy deleted the feat-gltf-clone-shader-materials branch December 21, 2018 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants