-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Bump into the latest glTF loader #4198
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
Conversation
package.json
Outdated
| "screenfull": "^4.0.1", | ||
| "semver": "^7.3.2", | ||
| "three": "github:mozillareality/three.js#hubs/master", | ||
| "three": "github:mozillareality/three.js#hubs/r128GLTFLoader", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Hubs-Foundation/three.js#57 is merged, I would update this line back to master in this PR or follow up PR. package-lock.json is same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually do it just before merging, and I leave a [ ] todo in the PR description to remind me
|
What I have tested so far.
|
netpro2k
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Definitely feels like a lot more of this is now being don the "right way'. Still some hacks in place but I think we have a clear path forward to improve most of them. Nice work!
package.json
Outdated
| "screenfull": "^4.0.1", | ||
| "semver": "^7.3.2", | ||
| "three": "github:mozillareality/three.js#hubs/master", | ||
| "three": "github:mozillareality/three.js#hubs/r128GLTFLoader", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually do it just before merging, and I leave a [ ] todo in the PR description to remind me
| afterRoot(gltf) { | ||
| gltf.scene.traverse(object => { | ||
| // GLTFLoader sets matrixAutoUpdate on animated objects, we want to keep the defaults | ||
| // @TODO: Should this be fixed in the gltf loader? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this was just copied over from our existing code, but it still does seem like the GLTFLoader should be respecting this default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think GLTFLoader should respect the default configuration, too. I'm going to suggest it to Three.js at some point. If it will be merged, we can drop this code.
src/components/gltf-model-plus.js
Outdated
| // When we replace our Three.js fork with the latest official one | ||
| // we need to revisit this workaround. | ||
| if (!parser.textureLoader.isImageBitmapLoader && typeof createImageBitmap !== undefined) { | ||
| parser.textureLoader = new THREE.ImageBitmapLoader(parser.options.manager); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ImageBitmapLoader returns an ImageBitmap not a Texture instance I thought. Doesn't this need to be a some kind of texture loader?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GLTFLoader makes CanvasTexture from ImageBitmap if textureLoader is ImageBitmapLoader so this line should be fine.
But this line may be confusing for people who don't know the inside of GLTFLoader. I will add comment.
src/components/gltf-model-plus.js
Outdated
| return; | ||
| } | ||
| const materials = Array.isArray(object.material) ? object.material : [object.material]; | ||
| // @TODO: Handle more efficiently |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are already overriding parser.textureLoader in the constructor. Seems like we can still use the HubsTextureLoader to take care of this no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't really want to override parser.textureLoader because GLTFLoader doesn't have a proper API to override the texture loader. Overriding parser.textureLoader = new CustomLoader() is hacky and the GLTFLoader doesn't expect the texture loader to be overridden. There might be a chance that it causes future errors especially when updating to the future glTF loader upstream.
I did override the texture loader because there doesn't seem to be other options to let GLTFLoader use ImageBitmapLoader for Firefox. Yes, overriding the texture loader is hacky as I wrote but GLTFLoader expects that the texture loader can be ImageBitmapLoader so I think it would be less problematic than using our custom texture loader. And if Firefox and Three.js will be updated to support ImageBitmapLoader we will be able to simply drop this hacky code.
But if we realize that this traverse is slow I want to revisit.
src/components/gltf-model-plus.js
Outdated
| node.extras.gltfIndex = i; | ||
| // | ||
| if (this.fileMap) { | ||
| // The GLTF is now cached as a THREE object, we can get rid of the original blobs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a mental note I re-remember while reading through this PR. This is to clean up the root level resources we create (from Sketchfab zip files) to load the GLTF.
Does the official GLTFLoader have any method of cleaning up the resources it creates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a plugin manage resources afterRoot hook would be a good place to release the resources.
| this.disposeLastInflatedEl(); | ||
|
|
||
| this.model = gltf.scene || gltf.scenes[0]; | ||
| this.model = gltf.scene; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this guaranteed to be set now? I think the reason we had it originally is that not GLTFs are not required to have a default scene (though almost all I have encountered in practice do).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's guaranteed in the latest GLTFLoader. IIRC the official loader didn't do that before so I think you encountered the problem with the old loader.
| // This plugin just wants to split gltf and bin from glb and | ||
| // doesn't want to start the parse. But glTF loader plugin API | ||
| // doesn't have an ability to cancel the parse. So overriding | ||
| // parser.json with very light glTF data as workaround. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hah nice workaround
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know that this workaround seems acceptable.
| this.inputFiles.bin = new File([body], "file.bin", { | ||
| type: "application/octet-stream" | ||
| await new Promise((resolve, reject) => { | ||
| // This GLTFBinarySplitterPlugin saves gltf and bin in inputFiles.gltf/bin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something about this feels a bit weird but I don't really have a much better idea. I maybe would have had the plugin just store it on itself rather than have it passed in and then done something like this after load:
this.inputFiles.gltf = binarySplitterPlugin.gltf;
this.inputFiles.bin = binarySplitterPlugin.bin;But not sure that is really much better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this?
await new Promise((resolve, reject) => {
// GLTFBinarySplitterPlugin saves gltf and bin in gltf.files
gltfLoader.load(gltfUrl, result => {
this.inputFiles.gltf = result.files.gltf;
this.inputFiles.bin = result.files.bin;
}, onProgress, reject);
});
|
I will remove my need to review, since you are both already experts in this code and Dom has done a thorough review. Thanks for getting this through! |
|
Thanks for the reviews. Just in case, I would like to inform you folks that please don't merge this PR and Hubs-Foundation/three.js#57 until we finish the test with the QA team. |
|
I just noticed (remembered) that the latest If we want to keep supporting DDS texture, we can use an external DDS texture plugin I wrote Any opinion on this? We should encourage KHR_texture_basisu, too, but also I think we don't need to drop DDS texture support and require the asset authors to update their works. |
|
Ah wait. I noticed that the current |
…esult should be compared with strings
|
I reverted the removal of As we internally discussed on Discord, we may disable Three.js entire cache so we may want to revisit later. I added a comment about why we use |
|
Somehow the glTF loader replacement resolves the Specular/Glossiness material problem #1613 The Specular/Glossiness material is rendered correctly on the testing server. |
|
Regarding I think it's ok because https://github.com/mozilla/hubs/blob/693dc621377734a5391e78e18c4d7a2c947b169d/src/components/gltf-model-plus.js#L515-L539 |
…dReality Three.js hubs/master branch
Requires: Hubs-Foundation/three.js#57
From: #4117
This PR replaces our Three.js glTF loader fork with the latest official Three.js one and updates
gltf-model-plus.jsandavatar-editor.jsto follow the latest official Three.jsGLTFLoaderAPI.Benefits
Please refer to #4117 (comment) for the changes.
Note that the changes in this PR is just for replacing the glTF loader. There may be a chance that they can be further cleaned up or optimized with the new API. But I would like to do them if needed in another PR because I don't want to make this PR bigger and the review harder.
TODO