-
Notifications
You must be signed in to change notification settings - Fork 252
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
Convert glTF 1.0 techniques to PBR materials by default #619
Conversation
I still need to test this with more assets, but @javagl maybe you would like to review? |
For testing - I wrote a script to convert all the glTF 1.0 sample models to 2.0: gltfConverter.js.zip And used this sandcastle to compare the results in CesiumJS: sandcastle. The sandcastle is partially auto-generated by the script. |
And just to point some the more noticeable breakages in the sandcastle:
|
The animation for I'm a bit stumped by this one, because ...
(except for the horrible PBR rendering... I never managed to allocate enough time for that one...)
https://cx20.github.io/gltf-test/examples/cesium/index.html?model=BoxAnimated So there does not seem to be a fundamental problem with the animation handling in general, but the conversion ... does something that causes some viewers to glitch out... This might, in fact, be related to (or have the same source as) CesiumGS/cesium#10621 I just started tests, will go though other models and then drop another note here. I haven't started with an actual "code review" yet (and depending on the expected depth of that, may have to read a bit of code beyond the changes here), but can try to focus on the actual changes during the review. |
Further test remarks:
The color changed when rotating the model. Unfortunately, the README does not say what exacty is tested with this model, but apparently, it was only a test for semantics handling, by basically mixing a bunch of semantic-based values into the color ...
This might warrant a second look: The result of converting the I noticed a strange effect for the This might be an issue of the conversion, but I wonder what could be causing this effect. |
The Cesium Man artifact is related to CesiumGS/cesium#6447 (comment). I think the glTF 2.0 version was fixed. |
Yeah, it's difficult: The
... and try to figure out which of these errors are caused by errors in the input data, and which ones are caused by the converter ... |
I'm still looking through the code, but there seems to have a test failure at
|
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.
- Some comments above may be worth another look.
- Some comments inlined.
Beyond that, the code looks fine for me (as far as I can 'understand' it in the given time).
I did not take a really close look at the Specs code in particular, but ran the glTF-Sample-Models conversion and the tests. If the Specs should be reviewed (as in: "Do the inputs/outputs make sense?", or "Is 'every reasonable corner case' covered with the spec?"), just drop me a note. But considering the legacy nature of the inputs, defining a 'reasonable corner case' could be hard...
@@ -101,6 +99,17 @@ function addDefaults(gltf) { | |||
values.shininess = defaultValue(values.shininess, 0.0); | |||
} | |||
} | |||
|
|||
// These actually exist on the extension object, not the values object despite what's shown in the spec |
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'm actually considering to bring that up in an issue in the glTF repo. But it's probably considered to be "too legacy" to be worth the noise...
function initializePbrMaterial(material) { | ||
material.pbrMetallicRoughness = defined(material.pbrMetallicRoughness) | ||
? material.pbrMetallicRoughness | ||
: {}; |
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've seen the use of the ternary operator and defined
at various places, e.g. things like
values.emission = defined(values.emission)
? values.emission
: [0.0, 0.0, 0.0, 1.0];
and wonder whether there is a reason to not use
values.emission = defaultValue(values.emission, [0.0, 0.0, 0.0, 1.0]);
for this.
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.
Only reason is to avoid the allocation if the left hand side is already defined. Though this code is only called once so defaultValue
would not cause much of a GC hit. I might just leave it as-is though both approaches are fine here.
: {}; | ||
|
||
material.pbrMetallicRoughness.roughnessFactor = 1.0; | ||
material.pbrMetallicRoughness.metallicFactor = 0.0; |
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.
It also always bugged me a bit, but the default value for the metallicFactor
is indeed 1.0 ( see https://github.com/KhronosGroup/glTF/blob/b6e0fcc6d8e9f83347aa8b2e3df085b81590a65c/specification/2.0/schema/material.pbrMetallicRoughness.schema.json#L30 ).
(Maybe the value of 0.0 is used intentionally here, but I wanted to mention it...)
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 set it to 0.0 intentionally since I think it makes for a better default, especially since the conversion is disregarding the specular values.
Trying to zoom a bit into the
The This might be a structural change that cannot be handled by the converter. (I'd have to re-read the 'animations' parts of the 1.0 spec and the 2.0 spec to be sure about the semantics and intended behavior of both...) (An aside: I verified that the relevant accessors contain all the same data in both version, so that's not the issue) |
I was surprised to see that even the converted
(several of that kind). I assume that this is the reason for many of the validation errors that I summarized above. I drafted a PR #620 that calls a function For the case of the I can imagine that calling this function might be costly for larger models (and maybe it should be possible to enable/disable this step with a command line parameter or so...), and I'm not 100% sure whether that's the right place of calling it and so. But maybe it's worth considering this, just for the validity sake... |
…minmax Validate accessor min/max values
@javagl I think this is good to merge, but I just wanted to make sure I didn't miss anything actionable from your comments |
Sorry, I should have tried to not comment so much as I went along, but rather try to write one, final, concise summary. What's left: Maybe low priority:
What may be higher priority: A test failure at
|
For whatever reason the glTF-Embeded and glTF-Binary versions do not have vertex colors, but the plain glTF does |
Ah, I knew I was missing something... Strange that CI didn't pick up on this. Maybe I just changed the test so it quantizes texcoords as well 🤷 |
I tried the latest state, and the test passes (although I won't claim to have understood what the test was testing). So I think that this PR could be merged. The following is probably unrelated to this PR: The validation on the output now yields
From a quick look each asset (in one particular version), the errors seem to be of the categories
These might all be due to the difficulties that arise from translating glTF 1.0 animations/skinning to the proper glTF 2.0 animations/skinning. Subtle details have changed there, and it's not even clear whether they can be updated automatically. So I assume that this is not considered to be an issue for now... |
Thanks @javagl, yeah, I would leave those are future work. |
Previously we would convert glTF 1.0 to 2.0 with the
KHR_techniques_webgl
extension which preserves the techniques and shaders but is not widely supported by runtimes because of its implementation complexity.This PR changes this behavior and tries to do a best effort upgrade from glTF 1.0 to glTF 2.0 with PBR materials. It does this by looking for common parameter names like "diffuse", "tex", etc and maps those to PBR material properties. This won't work for glTF 1.0 assets that rely on shader code for special lighting, billboard effects, or custom quantization/oct-decoding, but it works for most glTF 1.0 in the wild including all the sample models in https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/1.0
This whole process started because CesiumJS's glTF implementation is changing and can no longer support embedded shaders, but we still want to support as much of glTF 1.0 as possible. CesiumJS uses gltf-pipeline to upgrade glTF 1.0 to 2.0 already so it made sense to make the changes here. See CesiumGS/cesium#10414 and CesiumGS/cesium#10613 for more background.
For the previous behavior just pass in
--keepLegacyExtensions