diff --git a/src/mol-canvas3d/passes/pick.ts b/src/mol-canvas3d/passes/pick.ts
index 46e8ef8d7204db3b06716f1cd9831f06e1611ea4..59d332b8f155dcb4ff7b97a10374bb7975d374f9 100644
--- a/src/mol-canvas3d/passes/pick.ts
+++ b/src/mol-canvas3d/passes/pick.ts
@@ -11,14 +11,17 @@ import Scene from '../../mol-gl/scene';
 import { PickingId } from '../../mol-geo/geometry/picking';
 import { decodeFloatRGB } from '../../mol-util/float-packing';
 
-const readBuffer = new Uint8Array(4)
-
 export class PickPass {
     pickDirty = true
+
     objectPickTarget: RenderTarget
     instancePickTarget: RenderTarget
     groupPickTarget: RenderTarget
 
+    private objectBuffer: Uint8Array
+    private instanceBuffer: Uint8Array
+    private groupBuffer: Uint8Array
+
     private pickScale: number
     private pickWidth: number
     private pickHeight: number
@@ -31,18 +34,33 @@ export class PickPass {
         this.pickScale = pickBaseScale / webgl.pixelRatio
         this.pickWidth = Math.round(width * this.pickScale)
         this.pickHeight = Math.round(height * this.pickScale)
+
         this.objectPickTarget = createRenderTarget(webgl, this.pickWidth, this.pickHeight)
         this.instancePickTarget = createRenderTarget(webgl, this.pickWidth, this.pickHeight)
         this.groupPickTarget = createRenderTarget(webgl, this.pickWidth, this.pickHeight)
+
+        this.setupBuffers()
+    }
+
+    private setupBuffers() {
+        const bufferSize = this.pickWidth * this.pickHeight * 4
+        if (!this.objectBuffer || this.objectBuffer.length !== bufferSize) {
+            this.objectBuffer = new Uint8Array(bufferSize)
+            this.instanceBuffer = new Uint8Array(bufferSize)
+            this.groupBuffer = new Uint8Array(bufferSize)
+        }
     }
 
     setSize(width: number, height: number) {
         this.pickScale = this.pickBaseScale / this.webgl.pixelRatio
         this.pickWidth = Math.round(width * this.pickScale)
         this.pickHeight = Math.round(height * this.pickScale)
+
         this.objectPickTarget.setSize(this.pickWidth, this.pickHeight)
         this.instancePickTarget.setSize(this.pickWidth, this.pickHeight)
         this.groupPickTarget.setSize(this.pickWidth, this.pickHeight)
+
+        this.setupBuffers()
     }
 
     render() {
@@ -54,12 +72,35 @@ export class PickPass {
         renderer.render(scene, 'pickInstance', true);
         this.groupPickTarget.bind();
         renderer.render(scene, 'pickGroup', true);
+
+        this.pickDirty = false
+    }
+
+    private syncBuffers() {
+        const { webgl } = this
+
+        this.objectPickTarget.bind()
+        webgl.readPixels(0, 0, this.pickWidth, this.pickHeight, this.objectBuffer)
+
+        this.instancePickTarget.bind()
+        webgl.readPixels(0, 0, this.pickWidth, this.pickHeight, this.instanceBuffer)
+
+        this.groupPickTarget.bind()
+        webgl.readPixels(0, 0, this.pickWidth, this.pickHeight, this.groupBuffer)
+    }
+
+    private getId(x: number, y: number, buffer: Uint8Array) {
+        const idx = (y * this.pickWidth + x) * 4
+        return decodeFloatRGB(buffer[idx], buffer[idx + 1], buffer[idx + 2])
     }
 
     identify(x: number, y: number): PickingId | undefined {
         const { webgl, pickScale } = this
         const { gl } = webgl
-        if (this.pickDirty) this.render()
+        if (this.pickDirty) {
+            this.render()
+            this.syncBuffers()
+        }
 
         x *= webgl.pixelRatio
         y *= webgl.pixelRatio
@@ -68,19 +109,13 @@ export class PickPass {
         const xp = Math.round(x * pickScale)
         const yp = Math.round(y * pickScale)
 
-        this.objectPickTarget.bind()
-        webgl.readPixels(xp, yp, 1, 1, readBuffer)
-        const objectId = decodeFloatRGB(readBuffer[0], readBuffer[1], readBuffer[2])
+        const objectId = this.getId(xp, yp, this.objectBuffer)
         if (objectId === -1) return
 
-        this.instancePickTarget.bind()
-        webgl.readPixels(xp, yp, 1, 1, readBuffer)
-        const instanceId = decodeFloatRGB(readBuffer[0], readBuffer[1], readBuffer[2])
+        const instanceId = this.getId(xp, yp, this.instanceBuffer)
         if (instanceId === -1) return
 
-        this.groupPickTarget.bind()
-        webgl.readPixels(xp, yp, 1, 1, readBuffer)
-        const groupId = decodeFloatRGB(readBuffer[0], readBuffer[1], readBuffer[2])
+        const groupId = this.getId(xp, yp, this.groupBuffer)
         if (groupId === -1) return
 
         return { objectId, instanceId, groupId }