Picker Framebuffer Issue with Camera Movement and Screen Resize in v1.68.0

Dear PlayCanvas Team,

After updating to PlayCanvas version 1.68.0, the picker framebuffer no longer consistently selects the correct entity when I click on it. This issue seems to occur after I move the camera or change the screen size. For example, when I attempt to select a capsule entity, the picker sometimes incorrectly identifies and selects a brick entity instead, even though the capsule was clearly clicked. This behavior is inconsistent, and the selected entity varies without apparent reason.

Steps to Reproduce:

  1. Update PlayCanvas project to version 1.68.0.
  2. Implement a basic picker framebuffer setup to select entities on click.
  3. Move the camera or change the screen size.
  4. Attempt to select an entity by clicking on it.
  5. Observe that the wrong entity is sometimes selected.

below is my project.
https://playcanvas.com/editor/scene/1950243

below is the link for the video
https://filetalk.jp/download.php?cd=RcwnW6TmPs

Dear PlayCanvas Team,

Any update in this topic. Please let me know if there is any solution on this topic.

Thank you in advance.

Hi … I have not looked at your project, but we have an example using it here:
https://playcanvas.github.io/#/graphics/area-picker

and I cannot reproduce the error by changing the screen size. The example calls this each frame to handle it, is this something you do in your code as well?

        // Make sure the picker is the right size, and prepare it, which renders meshes into its render target
        if (picker) {
            picker.resize(canvas.clientWidth * pickerScale, canvas.clientHeight * pickerScale);
            picker.prepare(camera.camera, app.scene, pickerLayers);
        }

Hello @mvaligursky , Thank you for the reply. below is my code.
it does not selects the correct entity when I click on it.



var PickerFramebuffer = pc.createScript('pickerFramebuffer');

PickerFramebuffer.attributes.add('pickAreaScale', {
    type: 'number',
    title: 'Pick Area Scale',
    description: '1 is more accurate but worse performance. 0.01 is best performance but least accurate. 0.25 is the default.',
    default: 0.25,
    min: 0.01,
    max: 1
});

PickerFramebuffer.attributes.add('layerNames', {
    type: 'string',
    title: 'Layers Names',
    array: true,
    description: 'Layer names from which objects will be picked from.',
    default: ['World']
});

// initialize code called once per entity
PickerFramebuffer.prototype.initialize = function () {
    // Create a frame buffer picker with a scaled resolution
    var canvas = this.app.graphicsDevice.canvas;
    var canvasWidth = parseInt(canvas.clientWidth, 10);
    var canvasHeight = parseInt(canvas.clientHeight, 10);

    this.picker = new pc.Picker(this.app, canvasWidth * this.pickAreaScale, canvasHeight * this.pickAreaScale);
    this.layers = [];
    for (var i = 0; i < this.layerNames.length; ++i) {
        var layer = this.app.scene.layers.getLayerByName(this.layerNames[i]);
        if (layer) {
            this.layers.push(layer);
        }
    }

    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onSelect, this);

    this.on('destroy', function () {
        this.app.mouse.off(pc.EVENT_MOUSEDOWN, this.onSelect, this);
    }, this);
};

PickerFramebuffer.prototype.onSelect = function (event) {
    var canvas = this.app.graphicsDevice.canvas;
    var canvasWidth = parseInt(canvas.clientWidth, 10);
    var canvasHeight = parseInt(canvas.clientHeight, 10);

    var camera = this.entity.camera;
    var scene = this.app.scene;
    var picker = this.picker;

    if (picker) {
        picker.resize(canvasWidth * this.pickAreaScale, canvasHeight * this.pickAreaScale);
        picker.prepare(camera, scene, this.layers);
    }

    // Map the mouse coordinates into picker coordinates and 
    // query the selection
    var selected = picker.getSelection(
        Math.floor(event.x * (picker.width / canvasWidth)),
        picker.height - Math.floor(event.y * (picker.height / canvasHeight))
    );

    if (selected.length > 0) {
        // Get the graph node used by the selected mesh instance
        var entity = selected[0].node;
        console.log('selected entity :', entity);
    }
};

Can you log out what this gives you?
parseInt expects a string … but canvas.clientWidth is a number.