CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.85k stars 3.47k forks source link

Add mipmaps to textures in `ModelExperimental` #10231

Closed j9liu closed 2 years ago

j9liu commented 2 years ago

Currently, ModelExperimental's TextureManager doesn't handle mipmapping like GltfTextureLoader does. This was started in #10158, but there turned out to be more work involved and the PR has gone inactive. A thorough implementation would do the following:

jjhembd commented 2 years ago

Hi @j9liu, I started a draft PR addressing most of this issue. It follows your proposed strategy, with a few slight changes:

Handling the WebGL1 limitation (power-of-two dimension requirements) adds a lot of complexity. I wanted to separate out that complexity so that it can be easily removed whenever we drop WebGL1 support. The main createTexture function now looks like this:

  const texture = context.webgl2
    ? getTextureAndMips(textureUniform, image, context)
    : getWebGL1Texture(textureUniform, image, context);

and all the dimension checks and resizing are handled inside getWebGL1Texture.

I wrote unit tests for the helper functions (resizeImageToNextPowerOfTwo and getImageFromTypedArray), but I'm still working on the tests for the main TextureManager.

I'd appreciate your feedback on 2 things:

Thanks!

j9liu commented 2 years ago

Hi @jjhembd ,

I'll need a moment to leave more detailed feedback on your PR, but from a glance:

For testing both WebGL1 and WebGL2 contexts, you'll want to make two different scenes in the spec. The first one can be created normally with createScene(), we use WebGL1 by default. The scene with WebGL2 should be constructed like so:

      sceneWithWebgl2 = createScene({
        contextOptions: {
          requestWebgl2: true,
        },
      });

Then, in any unit test involving WebGL2, we have to check if the context was successfully requested. Otherwise, the unit test will fail. So we should put this at the beginning of the unit test:

      if (!sceneWithWebgl2.context.webgl2) {
        return;
      }

see ModelExperimentalSpec for how to do this, here and here