Dicsussion: Picking translucent positions not working as expected

I opened a ticket on github for this issue (https://github.com/AnalyticalGraphicsInc/cesium/issues/6151#issuecomment-360203739). To summarize: I exepcted setting scene.pickTranslucentDepth = true to allow for picking of translucent objects as stated in the docs https://cesiumjs.org/Cesium/Build/Documentation/Scene.html#pickTranslucentDepth.

As Hanna pointed out, this is not actually a bug. Calling scene.render() inbetween picks fixes the problem. I would like to continue the discussion here with the following: Thank you for the fix Hanna, it solves my problem. None the less I would like to reopen the issue, since the behaviour is not apparent from the documentation (and thus the title: not working as expected). Potentially an example could help out?

Best,
Ben

Hi Ben,

I reopened and renamed to issue to clarify the docs. If you want to make the change yourself and open a pull request, we’d appreciate the contribution!

Thanks,

Gabby

Hi Gaby,

thanks for your reply. I’d be glad to open a PR for this, once I’ve fully understood what it is that actually happens. I’ve been doing some digging (since I managed to provoke a state where the **UniformSampler **for the batchTexture had an undefined value when _setUniforms was called on the ShaderProgram, which causes rendering to stop This happened when adding a Primitive to the scene in a Promise while the globe tried to spin, but only when the camera is close to the ellipsoid. Sadly, I cannot reproduce this in a Sandcastle). And the results of my digging are:

  • Calling **scene.pickPosition ***before *pick or drillPick works fine.

  • Calling scene.pickPosition twice does not require a forced render.

  • Calling scene.pickPositon async after pick also does not require a forced render:
    viewer.scene.pickTranslucentDepth = true;

    viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
    var pickedFeature = viewer.scene.pick(movement.position);

    setTimeout(function() {

    console.log(viewer.scene.pickPosition(movement.position));

    }, 0);

    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    ``

The first two points I can make sense of: picking does something to the Context or FrameState which does not allow for picking the position of translucent primitives in the same frame. Is this assumption correct? The question which remains is: why does pickPosition not affect the next pick? What baffles me more is: why does calling it async work? Does the callback handler wait for the next animation frame before executing? What is more expensive/time consuming: forcing the scene to render or calling pickPosition async (the reasoning is: I’m trying to pick the position inside a Promise, so waiting for a frame is less obtrusive then blocking the client)? Once I’m clear on these points, I’ll add these conclusions to the docs to clarify pickTranslucentDepth.

Best,

Ben

For background, see the Rendering a Frame blog post section on “Picking”. However, pickPosition use the depth buffer instead of rendering the scene to separate colors. So it can’t use the previously rendered pick, we need to render a new frame.

Calling pickPosition before pick works because we can use the last frame. Likewise, calling pickPosition twice will also work, as both calls use the same frame. It’s difficult to tell what is going on when you call the function asynchronously, as new frames are being rendered in the meantime, so we can’t be exactly sure what order the renders and pick calls happen in.

Thanks,
Gabby

Hi Gaby,

thanks for the background infos! I think I’ll find the time over the weekend to formulate an addition to the docs regarding the issue.

Best,

Ben