`drillPickFromRay` objects have undefined position

I reproduced this in a Sandcastle.

In my specific case, position remains undefined because depth here is 0 (for all three frustums), because pixels here is [0, 0, 0, 0].

I realize drillPickFromRay is still private; I am using it to test for occlusion and would be very happy with another mechanism.

Made no difference:

  • Changing width of intersection volume.
  • Setting webgl.preserveDrawingBuffer to true.
  • Turning on/off requestRenderMode.
  • Turning on/off logarithmicDepthBuffer, pickTranslucentDepth.
  • Changing browsers and other environmental factors.
  • Upgrading to Cesium 1.77.

Additionally:

When retrying the same batch of rays, the same rays almost always fail regardless of the order in which they are processed; rarely, one that had previously failed will return a defined position.

Pickable primitives (in my case, spheres) that should be intersected by a ray also fail to be returned, and this (almost?) always happens when the position of the intersection with the model is undefined.

From memory all picks (apart from pickPosition()) are internally converted to ray picking, so I’m not entirely sure, but I’ll have a quick skim to see if something pops up. But again, like the previous post on the order of picking and the render cycle, I can reproduce your error with your example, but by moving the requestRender() to right after the pickPosition() I can not;

const position3d = scene.pickPosition(position);
scene.requestRender();

This will at least give you a point of entry to move forward.

Cheers,

Alex

Alex,

Thanks. I have tried inserting calls to requestRender and render at various times, and no combination has prevented the issue. E.g.:

drillPickFromRay is calling getRayIntersection to get the picked objects and their intersection position. The position is a function of the offscreen camera and the depth, which comes from pickDepth.getDepth(context, 0, 0):

PickDepth.prototype.getDepth = function (context, x, y) {
  // If this function is called before the framebuffer is created, the depth is undefined.
  if (!defined(this._framebuffer)) {
    return undefined;
  }

  var pixels = context.readPixels({
    x: x,
    y: y,
    width: 1,
    height: 1,
    framebuffer: this._framebuffer,
  });

  var packedDepth = Cartesian4.unpack(pixels, 0, scratchPackedDepth);
  Cartesian4.divideByScalar(packedDepth, 255.0, packedDepth);
  return Cartesian4.dot(packedDepth, packedDepthScale);
};

In this case, from what I can tell, this._framebuffer is defined and has one active color attachment and a 1x1 color texture. Presumably, at some point, the depth is encoded as an RGBA value with this or something like it. context.readPixels binds the framebuffer and reads the (only) bottom, left pixel. There are no apparent errors, and this value is [0, 0, 0, 0], which is just wrong.

I can’t tell if it was encoded incorrectly or it was cleared and 0 is the default or what. PickDepth does have an executeDebugPickDepth method, which I might try to use.

It seems noteworthy that the object is picked correctly and the same rays (in ostensibly the same scene) don’t always fail.

Hey,

That’s interesting; after I moved the requestRender() to just after the pickPosition() I couldn’t replicate your problem at all. I tested quite a lot. How odd.

But we need some heavy-duty Cesium pro’s on this case, I think. Anyone?

Cheers,

Alex