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

KTX2 integration -- Dropping support for KTX #9040

Closed
wants to merge 19 commits into from
Closed

Conversation

YVin3D
Copy link
Contributor

@YVin3D YVin3D commented Jul 20, 2020

  • Adds support for KTX2 textures
  • Drops support for KTX
  • Updates two sandcastles that used to contain KTX files (Materials & Image-Based Lighting)
  • Updates some specs that used to use KTX files.
  • Currently has unit tests for LoadKTX2.js that do not pass due to a race condition when calling .simulateError()

@cesium-concierge
Copy link

Thanks for the pull request @YoussefV!

  • ✔️ Signed CLA found.
  • CHANGES.md was not updated.
    • If this change updates the public API in any way, please add a bullet point to CHANGES.md.
  • ❔ Changes to third party files were made.
    • Looks like a file in one of our ThirdParty folders (ThirdParty/, Source/ThirdParty/) has been added or modified. Please verify that it has a section in LICENSE.md and that its license information is up to date with this new version.

Reviewers, don't forget to make sure that:

  • Cesium Viewer works.
  • Works in 2D/CV.
  • Works (or fails gracefully) in IE11.

@YVin3D YVin3D requested review from lilleyse and OmarShehata July 20, 2020 16:37
@YVin3D
Copy link
Contributor Author

YVin3D commented Jul 20, 2020

PS. Need to update CHANGES.md and run prettier when everything is done (before merge)

@lilleyse
Copy link
Contributor

@YoussefV two high level things:

  • You can remove crn (Crunch) support as well. Just add it to a breaking changes section in CHANGES.md.
  • Does the Basis transcoder support Internet Explorer? IE does not support WebAssembly so for Draco we had to create a special build as described here: DracoModuleManagement.
    • It might be fine to merge this PR anyways, but we'll have to decide whether we should use KTX2/Basis by default in the tiling pipeline or if we need to provide some fallback.
    • We should find the % of devices that don't support any GPU compressed texture formats, also to help us determine if we need to provide fallbacks in ion.

@lilleyse
Copy link
Contributor

@YoussefV could you add a KTX2/Basis sample to 3d-tiles-samples-generator? That's where we generate all the test tilesets. I opened CesiumGS/3d-tiles-samples-generator#5 with more info. That sample will replace the balloon tileset in this PR.

@YVin3D
Copy link
Contributor Author

YVin3D commented Jul 22, 2020

@lilleyse So should we not include the Balloon 3DTile in this PR?

@lilleyse
Copy link
Contributor

@YoussefV yes, the balloon tileset can be removed once the other sample is generated

@lilleyse
Copy link
Contributor

Why was Apps/Sandcastle/images/whiteShapes.png removed?

@YVin3D
Copy link
Contributor Author

YVin3D commented Jul 22, 2020

Why was Apps/Sandcastle/images/whiteShapes.png removed?

It showed up as a white thumbnail on my computer, which is exactly how old ktx pictures looked like. So I accidentally deleted it while clearing out old .ktx files. Added it back in the latest commit. My bad!

// 1 - Download the Filament release (https://github.com/google/filament/releases).
// 2 - Run `cmgen --type=ktx --deploy=/path/to/output /path/to/image.hdr`. Other formats are also supported. Run `cmgen --help` for all options.
// 3 - Take the generated coefficients and the KTX file and load them in CesiumJS as shown below.
// This environment map was processed using Google's Filament project.

Copy link
Contributor

@OmarShehata OmarShehata Jul 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these instructions out of date/not working?

One problem we had when initially creating this Sandcastle is it was completely opaque what all these coefficients meant, or how to get your own. The user was never supposed to do this process manually. The glTF IBL extension just wasn't ready at the time.

But now it is: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_lights_image_based#ext_lights_image_based.

This example can be greatly simplified into essentially one line if we just add support for that extension. I would suggest we do that (not necessarily in this PR, open an issue for it?), and/or just remove this example because it isn't very useful to Cesium users as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, Google's Filament hasn't been updated to support KTX2. I had to rebuild this cubemap by using this website, which gave six PNG images, which I then had adjust the opacity of and then convert to KTX2 using the command line tool from this repo.

We could always open up an issue to build a tool that automates this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One limitation of using EXT_lights_image_based is that it needs to be added to the glTF's individually whereas Cesium users might want to set an environment map for the entire scene.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It's critical for users to be able to select their own HDR, IBL environments. Can't expect ordinary models to bundle them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would most users know how to/want to manually specify the 9 coefficients as shown here? That was the part I was thinking we could omit from this sandcastle, and fallback to the procedural.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you fall back to procedural, the diffuse lighting on the model won't match the specular lighting environment, which is not what a user who cares about lighting environments is going to want to see. That said, I'm no fan of manually specifying spherical harmonics in code, that seems ridiculous and error-prone. But is the alternative to force all users to always accept a default procedural diffuse lighting environment?

By comparison, BabylonJS stores pre-filtered lighting environments in .env files of their own design, which users can create in their Sandbox (instructions). The .env file contains both diffuse and specular lighting pre-filtered, making it ready to render models with. I don't know if the format is standard or open, but I suppose we could ask. For users this is very easy, just load the env and assign it to the scene, and all your models will have the correct lighting and reflections of the environment.

In ThreeJS, they can now load *.hdr files directly. But these need some pre-filtering at load time, and they have a class called PMREMGenerator that will do exactly this. This costs some load-time performance, but offers users the convenience of directly using the most common HDR environment format found online.

I like the KTX file, but it looks like the file is only storing the pre-filtered specular lighting environment, and dumping out the diffuse as a bunch of SH coefficients for users to deal with separately. Unless maybe KTX2 has some way to include the diffuse environment as well? Ideally there should be a standard environment format that includes both.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been working on the VSCode glTF preview, trying to get nice IBLs in all the preview windows, and it would be nice to include Cesium in this too.

In this commit I hacked up a little sh.txt file reader, which is the text file that cmgen writes out when it processed an IBL into a KTX. It loads the Spherical Harmonics and builds the array of Cartesians for them. Not sure if this will actually get published, but it seems to work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Watching a Virtual SIGGRAPH presentation on Filament (Moving Mobile Graphics, ~2:28:00). Romain says they're not using spherical harmonics at all anymore. Instead, they stop the specular IBL mipmaps at 16x16 smallest size with roughness == 1.0 at that size, and they re-use that particular mip level as their diffuse IBL.

I think Cesium should do that too, and ditch the SH coefficients.

// 1 - Download the Filament release (https://github.com/google/filament/releases).
// 2 - Run `cmgen --type=ktx --deploy=/path/to/output /path/to/image.hdr`. Other formats are also supported. Run `cmgen --help` for all options.
// 3 - Take the generated coefficients and the KTX file and load them in CesiumJS as shown below.
// This environment map was processed using Google's Filament project.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The environment map looks different than master. Is this because the image changed or did the IBL implementation change? The environment map should come with a prefiltered mipmap so that rougher materials produce blurrier reflections. Filament was doing this previously but I'm not sure what the new KTX2 generation process is like.

More background: https://learnopengl.com/PBR/IBL/Specular-IBL

ibl_prefilter_map

From the Image-Based Lighting sandcastle:

master

before

ktx2-integration

after

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the new image is 4.28MB compared to the previous 2MB. The smaller the better so that we don't bloat the CesiumJS zip release too much.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YoussefV you mentioned that a straight up KTX -> KTX2 conversion failed. How quick would it be to write our own script just for this? I guess this depends on the number of breaking changes between KTX and KTX2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would take a while because the spec has changed a decent amount. It might be worth it to open an issue in the KTX2 repo about it if we're 100% confident the original KTX file is valid.

The reason why the KTX2 file is larger is because the mip map is uncompressed, so it unpacks the RGB values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I was the one who created the KTX2 image, the mip map didn't make the reflections blurrier because it autogenerated the levels without taking into account it was a specular IBL. I think the best approach here is to fix the existing converter since the problem may most likely be that the converter has a bug.

I'll open up an issue there.

Source/Core/VulkanConstants.js Outdated Show resolved Hide resolved
Source/Core/VulkanConstants.js Outdated Show resolved Hide resolved
Source/Core/VulkanConstants.js Show resolved Hide resolved
Source/Scene/Model.js Outdated Show resolved Hide resolved
Specs/Renderer/TextureSpec.js Outdated Show resolved Hide resolved
Specs/Renderer/TextureSpec.js Outdated Show resolved Hide resolved
Specs/Renderer/TextureSpec.js Outdated Show resolved Hide resolved
@@ -113,7 +113,7 @@ describe(
sampleOctahedralMap(octahedralMap, directionFlipY, lod, function (
octahedralMapColor
) {
return expect(cubeMapColor).toEqualEpsilon(octahedralMapColor, 5);
return expect(cubeMapColor).toEqualEpsilon(octahedralMapColor, 7);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember talking about this offline. Once #9040 (comment) is addressed it should be fine to use 5 again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That probably explains that. Ok will do!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to this: the bug currently seems to be with Filament generating an invalid KTX file. More Here

@lilleyse
Copy link
Contributor

lilleyse commented Jul 22, 2020

Few miscellaneous things:

  • Probably best to remove compressedImage3DTiles everywhere like what we did in Added support for KTX2 texture files, dropped support for KTX and CRN… gltf-pipeline#550. Include this change in the breaking changes section in CHANGES.md.
  • In the breaking changes section also mention that KTX and CRN support is removed. Point to the KTX->KTX2 converter as a suggested fallback for users with KTX textures.
  • Remove crunch references from gulpfile.cjs. Here and here.
  • The KTX models in Specs/Data/Models need to be cleaned up. There's a weird mix of things going on.
    • Box-Textured-KTX is a glTF 1.0 model with the KHR_texture_basisu extension, which isn't valid
    • Anything ending with OLD can be removed
    • It looks like Box-Textured-KTX-Binary and Box-Textured-Embedded were converted from their glTF 1.0 counterpart and now use the KHR_techniques_webgl extension (when gltf-pipeline upgrades glTF 1.0 to 2.0 it adds the KHR_techniques_webgl to preserve the glTF 1.0 shaders) . Technically valid, but it would be simpler if it was just a normal glTF model with the basis extension.
    • Overall suggestion here: let's follow what Box-Textured-Webp does - for KTX2, remove the existing KTX test models and add just a single test model called Box-Textured-KTX2-Basis that is glTF 2.0, doesn't use KHR_techniques_webgl, and uses KHR_texture_basisu.
  • Add KHR_texture_basisu to the list of supported extensions in the documentation above the Model constructor and Model.fromGltf

Youssef's Comment: All of the above comments have been addressed in latest commit.

@lilleyse
Copy link
Contributor

@YoussefV do you by chance have a code example for testing KTX2 as a SingleTileImageryProvider? I'm curious to see if it works there.

@lilleyse
Copy link
Contributor

Ok that should be it for my first round of reviews. I haven't actually looked at loadKTX2 yet, just want to get the miscellaneous stuff out of the way first.

Aside from mostly minor comments, so far so good.

@YVin3D
Copy link
Contributor Author

YVin3D commented Jul 22, 2020

* Add `KHR_texture_basisu` to the list of supported extensions in the documentation above the `Model` constructor and `Model.fromGltf`

Technically, this isn't released yet, so I have no "official" link for this as in here, would I just include the link to the relevant PR?

@lilleyse
Copy link
Contributor

Technically, this isn't released yet, so I have no "official" link for this as in here, would I just include the link to the relevant PR?

Linking to the PR is fine. If this PR gets merged before KHR_texture_basisu is added to https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos you should open a CesiumJS issue that reminds us to update the link once ready.

@YVin3D
Copy link
Contributor Author

YVin3D commented Jul 22, 2020

@lilleyse made an incremental push with most of your comments addressed, there still remains a few which are not struck out above. I removed the commented code in TextureSpec.js, the failing tests are in LoadKTX2Spec.js:

This test: returns a promise that rejects when the request errors is the best example.

@YVin3D
Copy link
Contributor Author

YVin3D commented Jul 22, 2020

@YoussefV do you by chance have a code example for testing KTX2 as a SingleTileImageryProvider? I'm curious to see if it works there.

Talked about this offline, it works with the Imagery Layers sandcastle, just replace the filename to Logo.ktx2

@cesium-concierge
Copy link

Thanks again for your contribution @YoussefV!

No one has commented on this pull request in 30 days. Maintainers, can you review, merge or close to keep things tidy?

I'm going to re-bump this in 30 days. If you'd like me to stop, just comment with @cesium-concierge stop. If you want me to start again, just delete the comment.

@lilleyse
Copy link
Contributor

@cesium-concierge stop

@@ -173,6 +172,8 @@ var uriToGuid = {};
* {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_techniques_webgl/README.md|KHR_techniques_webgl}
* </li><li>
* {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md|KHR_texture_transform}
* </li><li>
* {@link https://github.com/KhronosGroup/glTF/pull/1751|KHR_texture_basisu}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I closed #9054, we can get the fix into this PR now.

@likangning93
Copy link
Contributor

likangning93 commented Oct 12, 2020

the tale of box-textured-basis.gltf

@lilleyse asked me to take a look at what's still needed to get this PR production-ready. Part of that was investigating why a model with KTX2 texture (ETC1S) from gltfpack was loading in Don Mccurdy's three-gltf-viewer but not in this branch.

box-textured.zip
localhost sandcastle - assumes model is in SampleData/models/KTX2

Specifically, this branch was getting:

KTX2 Loading Error:
RuntimeError: Error transcoding Image

Here are my observations and larger questions from my investigation:

transcoder interface change!

I started reading the code here and the doc for the transcoder wrapper, and I noticed that the interfaces seemed considerably different. As far as I can tell the interface changed somewhere around KhronosGroup/KTX-Software@5366cd1#diff-d620c588208646e4731bb46c099148e8L454

I have a WIP commit here that brings a newer build in and fixes some other bugs that were causing transcoding specifically to fail: 1addfe6
I tracked some of these down by debugging Cesium side-by-side with three-gltf-viewer.

[EDIT] fixed in d4a02b7

The newest version of the transcoder also looks to support UASTC encoding, which this PR currently does not support.

need to handle mip levels

My testing branch seems to transcode correctly but still has trouble making the texture with all the mip levels. Looking at our Texture.js it looks like we support pre-generated mip levels in Cesium, so hopefully this is just a wiring thing.

Note that box-textured doesn't have any samplers - we should follow the spec: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu

[EDIT] fixed in d4a02b7

should we check for more compressed texture extensions?

cesium context doesn't check for as many compressed texture extensions as three.js seems to. See:

https://github.com/CesiumGS/cesium/blob/master/Source/Renderer/Context.js#L308 vs. https://github.com/mrdoob/three.js/blob/dev/examples/jsm/loaders/KTX2Loader.js#L81.

This may need additional investigation and might not be actionable in this PR, but any changes to the compressed texture formats that we check for will probably necessitate changes to the logic in this branch for picking target texture formats.

how can we avoid monkeypatching the transcoder's built files?

Building the KTX2 web transcoder produces msc_basis_transcoder.js and msc_basis_transcoder.wasm.

The msc_basis_transcoder.js in this branch (and also in my WIP branch) has been monkeypatched to include export default and a modified path to the .wasm file in Cesium's project structure, which seems unsafe. I don't know how/whether this works with built Cesium.

[EDIT] My testing seems to show that the deployed, built version of this branch isn't working due to wasm loading problems, see here on Sandcastle.

Fixed in 6358371

other TODOs I'd like to get in:

@ebogo1 ebogo1 mentioned this pull request Apr 27, 2021
21 tasks
@ebogo1
Copy link
Contributor

ebogo1 commented Apr 27, 2021

continued in #9513...

@ebogo1 ebogo1 closed this Apr 27, 2021
@ebogo1 ebogo1 deleted the ktx2-integration branch April 29, 2021 14:47
@lilleyse lilleyse restored the ktx2-integration branch April 30, 2021 20:37
@ebogo1 ebogo1 mentioned this pull request May 12, 2021
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.

7 participants