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