Brown metallic reflection

I’ll see if my customer can change this locally

If that refers to that code change of using context.uniformState.enuToModel, then I should emphasize that this is not a “proposed solution”. It was only something that apparently “happened to work”, and it has to be checked in how far that makes sense.

(That enuToModel matrix actually depends on the view, and not on the model itself, so it’s unlikely that this is the right solution. But it may be a hint that the ENU-to-fixed-frame transform of the model position will have to be taken into account there, somehow…)

In terms of other quick fixes or workarounds: When loading a single model, then it may be possible to set the referenceMatrix manually.
(With the “tiny” ( :grimacing: ) degree of freedom: To which value?)

But when these models are part of a tileset, then it’s more tricky. (And I did spend a bit more time than I’d like to admit with zooming into that)

The first question is: What is actually wrong there? And the possible answers are

  1. the value of the referenceMatrix
  2. using the referenceMatrix in that computation
  3. both of the above
  4. none of the above
  5. something completely different :slight_smile:

Given that the meaning and purpose of the referenceMatrix is not clear for me, it’s hard to say what is the case here. Looking at the code, one can see that the referenceMatrix is set to be the tileset.clippingPlanesOriginMatrix in each frame. (What do clipping planes have to do with image based lighting? Probably nothing. But that’s the way it is…). The clippingPlanesOriginMatrix is also updated in each frame, based on the _initialClippingPlanesOriginMatrix. And this one should be initialized to be the ENU-to-fixed-frame matrix at the center of the tileset. But it isn’t… at least, not really. It is supposed to be initialized in this line, but this line is not executed here. The initial bounding sphere that is computed there does not take into account the root transform (!) of the tileset, meaning that the originCartographic.height there is -6371450.300484946.

So… lots of matrices here, and possible reasons for the issue: It might be that this particular issue is not even caused by the linked issue, but rather by a wrong computation of the _initialClippingPlanesOriginMatrix. (Even though this should have nothing to do with image based lighting after all…).

However, a tl;dr:

The following seems to cause the tileset to be displayed correctly. But this is also not a recommended solution, obviously. There are quite a few things to be sorted out here…

const viewer = new Cesium.Viewer("cesiumContainer", {
  globe: false
});

const tileset = viewer.scene.primitives.add(
  await Cesium.Cesium3DTileset.fromUrl(
    "http://localhost:8003/tileset.json", {
      debugShowBoundingVolume: true,
    }
  )
);

const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(
  tileset.boundingSphere.center,
  Cesium.Ellipsoid.WGS84,
  new Cesium.Matrix4(),
);
// XXX Private variable access!
tileset._initialClippingPlanesOriginMatrix = matrix;

const offset = new Cesium.HeadingPitchRange(
  Cesium.Math.toRadians(-135.0),
  Cesium.Math.toRadians(-22.5),
  8000.0
);
viewer.zoomTo(tileset, offset);