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, GLTFExporter: Remove KHR_materials_pbrSpecularGlossiness #24950

Merged
merged 2 commits into from
Nov 15, 2022

Conversation

donmccurdy
Copy link
Collaborator

@donmccurdy donmccurdy commented Nov 14, 2022

The Khronos Group archived the KHR_materials_pbrSpecularGlossiness extension ("no longer recommended for creating new files") about a year ago. I think it would be reasonable for us to remove support at this point, and focus efforts on the metal/rough workflow instead. All new and upcoming PBR features — volumetric refraction, iridescence, clearcoat, subsurface scattering, ... — are authored around the metal/rough model. With support for KHR_materials_ior and KHR_materials_specular, there is no particular advantage left to the spec/gloss model.

Existing spec/gloss models can be converted losslessly to metal/rough with:

npm install --global @gltf-transform/cli

gltf-transform metalrough in.glb out.glb

Related:

Migration guide:

@donmccurdy
Copy link
Collaborator Author

/cc @takahirox

@takahirox
Copy link
Collaborator

I think it's ok to remove them. For users who still need the extension, we can provide the plugins at or somewhere else.

https://github.com/takahirox/three-gltf-extensions

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Nov 14, 2022

@elalish following up on #23630 (comment) — the web app https://gltf.report will now do the spec/gloss → metal/rough conversion automatically. The same conversion could be applied in other web-based tools, with:

import { WebIO } from '@gltf-transform/core';
import { KHRONOS_EXTENSIONS } from '@gltf-transform/extensions';
import { metalRough } from '@gltf-transform/functions';

const io = new WebIO().registerExtensions(KHRONOS_EXTENSIONS);

const document = await io.readBinary(byteArray);

// spec/gloss → metal/rough
await document.transform(metalRough());

const glb = await io.writeBinary(document);

@mrdoob
Copy link
Owner

mrdoob commented Nov 15, 2022

I also think it's time 👍

@mrdoob mrdoob added this to the r147 milestone Nov 15, 2022
@mrdoob mrdoob merged commit e29c14b into mrdoob:dev Nov 15, 2022
@donmccurdy donmccurdy deleted the cleanup/gltfloader-remove-specgloss branch November 15, 2022 11:13
@elalish
Copy link
Contributor

elalish commented Nov 21, 2022

SG, thanks @donmccurdy! Now I just need to remember to point people to that tool in our next release notes.

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Nov 29, 2022

Also, here's a migration guide for converting existing glTF files:

@takahirox
Copy link
Collaborator

It's good to add it to the Three.js migration guide? https://github.com/mrdoob/three.js/wiki/Migration-Guide

@donmccurdy
Copy link
Collaborator Author

Thanks, I'd missed that it covered r147 already — done!

@elalish elalish mentioned this pull request Dec 12, 2022
@elalish
Copy link
Contributor

elalish commented Dec 12, 2022

@donmccurdy Does gltf-transform work in the browser so that I could add this conversion to our editor?

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Dec 12, 2022

@elalish the script above, #24950 (comment), will work in a browser, yes. 👍

What I'd do would be to load from the URL or DataTransfer API into glTF Transform, then export a GLB as Uint8Array, and to parse or load from a Blob URL in THREE.GLTFLoader from there. Happy to take questions in discussions as well!

@andybak
Copy link

andybak commented Nov 20, 2024

For future reference - there's a lot of models out there and a lot of code out there that still use KHR_materials_pbrSpecularGlossiness and I personally feel that backwards compatibility should be given a higher priority than it seems to have had here. Pre-processing gltf files is not an option in many cases (i.e. when you have no control over provenance).

I'll try and find time to contribute a plugin to handle this on import.

@elalish
Copy link
Contributor

elalish commented Nov 20, 2024

Our editor does the conversion on import - it's open source so you're welcome to crib the code if it's helpful: https://modelviewer.dev/editor/

@andybak
Copy link

andybak commented Nov 21, 2024

@elalish Thanks I'll take a look.

(I just spotted that you're behind manifold as well - I'd love to chat to you about that also at some point!)

@mrdoob
Copy link
Owner

mrdoob commented Nov 21, 2024

@elalish How does the conversion code look like? Is it small enough that we could add it to GLTFLoader?

@elalish
Copy link
Contributor

elalish commented Nov 21, 2024

Well, we just took a dependency on gltf-transform, which is probably heavier than what you want. You could look into extracting just that part of @donmccurdy's code - might not be too bad.

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Nov 21, 2024

Right, glTF Transform is about 20kb minzipped, plus any extensions you need. Fine for processing user uploads, but pre-processing the model offline would clearly be preferable for production. The conversion work is mainly rewriting textures...

https://github.com/donmccurdy/glTF-Transform/blob/84f1629e08750b61ce6ab344168dd6033d4656ee/packages/functions/src/metal-rough.ts#L81-L106

... which isn't a lot of code to re-implement, but is (1) slow, and (2) dependent on Canvas 2D or WebGL or WebGPU, which GLTFLoader otherwise would not require. My main concern was/is complexity and maintenance of GLTFLoader.

@mrdoob
Copy link
Owner

mrdoob commented Nov 22, 2024

I think being dependent on Canvas 2D is okay. And also that it's slow.

We could log a message saying that the textures got converted and suggest using glTF Transform.

I think that's better than just black?

@donmccurdy
Copy link
Collaborator Author

With one the edge case that we can't convert KTX2 textures so easily (but surely that combination is rare...) I think that would work well enough. If someone would like to open a PR rewriting spec/gloss textures to spec/rough (as in the link above), that sounds good to me.

@Jeggery
Copy link

Jeggery commented Dec 2, 2024

With one the edge case that we can't convert KTX2 textures so easily (but surely that combination is rare...)

So does Threejs GLTFExporter support ktx2 textures?

@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Dec 2, 2024

When you load KTX2 textures in three.js, they become THREE.CompressedTexture instances. When exporting materials with THREE.CompressedTexture textures using THREE.GLTFExporter, the textures are automatically decompressed to PNG or JPG images for export. The exporter cannot transcode backwards from the GPU texture format to the Basis Universal (BasisLZ / ETC1S / UASTC) encoding to produce a universal KTX2 texture.

@Jeggery
Copy link

Jeggery commented Dec 3, 2024

When you load KTX2 textures in three.js, they become THREE.CompressedTexture instances. When exporting materials with THREE.CompressedTexture textures using THREE.GLTFExporter, the textures are automatically decompressed to PNG or JPG images for export. The exporter cannot transcode backwards from the GPU texture format to the Basis Universal (BasisLZ / ETC1S / UASTC) encoding to produce a universal KTX2 texture.

Okay, thank you for your answer. I understand now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants