Skip to content

Commit f99b0ca

Browse files
committed
fix: solve picker bug
1 parent fec233d commit f99b0ca

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

packages/core/src/core/FastModelPicker/src/fast-model-picker.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,16 @@ export class FastModelPicker implements Disposable {
508508
// scene with lots of overdraw — collapses to ~O(SCISSOR_PX²).
509509
// 4×4 leaves a 1-pixel margin around the read site to absorb any
510510
// sub-pixel rounding in NDC→pixel conversion without missing.
511+
//
512+
// DPR caveat: `WebGLRenderer.setScissor` always multiplies its
513+
// arguments by the canvas pixelRatio before forwarding to GL,
514+
// even when the active target is an offscreen FBO at a different
515+
// resolution. The picker's FBO is sized in CSS pixels via
516+
// `renderer.getSize()`, so on a hi-DPI display passing FBO-pixel
517+
// coordinates straight through lands the GL scissor outside the
518+
// FBO — every read pixel comes back zero. Pre-divide by the
519+
// pixel ratio so three's multiplication restores the FBO-pixel
520+
// coords we want.
511521
const SCISSOR_PX = 4;
512522
const tw = target.width;
513523
const th = target.height;
@@ -518,7 +528,13 @@ export class FastModelPicker implements Disposable {
518528
const half = SCISSOR_PX >> 1;
519529
const sx = Math.max(0, Math.min(tw - SCISSOR_PX, cx - half));
520530
const sy = Math.max(0, Math.min(th - SCISSOR_PX, cy - half));
521-
renderer.setScissor(sx, sy, SCISSOR_PX, SCISSOR_PX);
531+
const dpr = renderer.getPixelRatio();
532+
renderer.setScissor(
533+
sx / dpr,
534+
sy / dpr,
535+
SCISSOR_PX / dpr,
536+
SCISSOR_PX / dpr,
537+
);
522538
renderer.setScissorTest(true);
523539

524540
const objectsByModel = new Map<string, THREE.Object3D>();

0 commit comments

Comments
 (0)