Gpu picker multi pick adjust to dpr

This topic is derived from the previous one.

I read the source code of the multiPickAsync function in the gpu picker and found that the function did not process the passed screen coordinate array to adapt to the dpr

source code link:https://github.com/BabylonJS/Babylon.js/blob/a56427494c5a8741d488e2e6a5bdb24e8f3488ac/packages/dev/core/src/Collisions/gpuPicker.ts#L408

This is the modified code. It works fine when dpr is not 1.

      async multiPickAsync(xy, disposeWhenDone = false) {  
        if (this._pickingInProgress) {  
            return null;  
        }  
        if (!this._pickableMeshes || this._pickableMeshes.length === 0 || xy.length === 0) {  
            return null;  
        }  
        if (xy.length === 1) {  
            const pi = await this.pickAsync(xy[0].x, xy[0].y, disposeWhenDone);  
            return {  
                meshes: [pi?.mesh ?? null],  
                thinInstanceIndexes: pi?.thinInstanceIndex ? [pi.thinInstanceIndex] : undefined,  
            };  
        }  
        this._pickingInProgress = true;  
    
        const processedXY = new Array(xy.length);

        let minX = Infinity;
        let maxX = -Infinity;
        let minY = Infinity;
        let maxY = -Infinity;

        // Process screen coordinates adjust to dpr
        for (let i = 0; i < xy.length; i++) {
            const item = xy[i];
            const { x, y } = item;

            const { x: adjustedX, y: adjustedY } = this._prepareForPicking(x, y);

            processedXY[i] = {
                ...item,
                x: adjustedX,
                y: adjustedY,
            };

            minX = Math.min(minX, adjustedX);
            maxX = Math.max(maxX, adjustedX);
            minY = Math.min(minY, adjustedY);
            maxY = Math.max(maxY, adjustedY);
        }
        
        const { rttSizeW, rttSizeH } = this._prepareForPicking(minX, minY);
        const w = Math.max(maxX - minX, 1);  
        const h = Math.max(maxY - minY, 1);  
        const partialCutH = rttSizeH - maxY - 1;  
    
        this._preparePickingBuffer(this._engine, rttSizeW, rttSizeH, minX, partialCutH, w, h);  
        return this._executeMultiPicking(xy, minX, maxY, rttSizeH, w, h, disposeWhenDone);  
    }

last topic:https://forum.babylonjs.com/t/gpu-multi-picking-issues/58074

here is fix multiPickAsync PG: https://playground.babylonjs.com/#W2D1C2#29

wanna do a PR?

I have submitted a PR:https://github.com/BabylonJS/Babylon.js/pull/16537 :grinning_face_with_smiling_eyes:

1 Like

looks good!

2 Likes