# THREE.Points use GPU Picking is not work

**URL:** <https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045>\
**Category:** Questions\
**Tags:** points\
**Created:** [August 14, 2019, 1:43pm UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045 "2019-08-14T13:43:57Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![xjindf](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/xjindf/32/24657_2.png) [@xjindf](https://discourse.threejs.org/u/xjindf)\
**Post date:** [August 14, 2019, 1:43pm UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045/1 "2019-08-14T13:43:57Z")

</div>

Hello, everybody.  
I’m using [https://threejs.org/examples/webgl\_custom\_attributes\_points](https://threejs.org/examples/webgl_custom_attributes_points) for 3 cases. It’s beautiful！！！  
but when I use the method of picking points with GPU in my article, I get the color ID ID when I combine it with [https://threejs.org/examples/webgl\_interactive\_cubes\_gpu](https://threejs.org/examples/webgl_interactive_cubes_gpu). Always scene background color, I do not know why, I do not know if anyone has encountered this situation, hope to help me, thank you!

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [August 15, 2019, 8:13am UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045/2 "2019-08-15T08:13:57Z")

</div>

Hi!  
Would be great to provide an editable live code example (codepen, jsfiddle etc., at last a repo on github) that shows the problem.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [August 15, 2019, 9:06am UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045/3 "2019-08-15T09:06:51Z")

</div>

It seems this (unofficial) demo with `three.js` does demonstrate GPU picking with points.

> **[GPU Picking (Three.js)](https://bl.ocks.org/duhaime/1eafa293e7ce16b074a6d55cac67badc)**
>
> Douglas Duhaime’s Block 1eafa293e7ce16b074a6d55cac67badc

---

<div class="post-metadata">

**Author:** ![xjindf](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/xjindf/32/24657_2.png) [@xjindf](https://discourse.threejs.org/u/xjindf)\
**Post date:** [August 15, 2019, 9:13am UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045/4 "2019-08-15T09:13:43Z")

</div>

```
//set the view offset to represent just a single pixel under the mouse,When THREE.Points is used in scenarios, it cannot be picked up correctly.
self.camera.setViewOffset(self.renderer.domElement.width, self.renderer.domElement.height, mouse.x * window.devicePixelRatio | 0, mouse.y * window.devicePixelRatio | 0, 1, 1);
self.renderer.setRenderTarget(self.pickingTexture);
self.renderer.render(self.pickingScene, self.camera);
self.camera.clearViewOffset();
self.renderer.readRenderTargetPixels(self.pickingTexture, 0, 0, 1, 1, pixelBuffer);

//Use the following code GPU to picking the normal work
self.renderer.setRenderTarget(self.pickingTexture);
self.renderer.render(self.pickingScene, self.camera);
self.renderer.readRenderTargetPixels(self.pickingTexture, mouse.x, self.pickingTexture.height - mouse.y, 1, 1, pixelBuffer);
```

---

<div class="post-metadata">

**Author:** ![xjindf](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/xjindf/32/24657_2.png) [@xjindf](https://discourse.threejs.org/u/xjindf)\
**Post date:** [August 15, 2019, 9:16am UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045/5 "2019-08-15T09:16:55Z")

</div>

> [@xjindf](#):
>
> pickingTexture

THREE. Points picked up invalid when I used the latest improved camera. setViewOffset offset to get 1 pixel, and other models were normal. I don’t know what’s wrong with using the old full screen rendering to picking Texture.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [August 15, 2019, 9:35am UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045/6 "2019-08-15T09:35:49Z")

</div>

> [@xjindf](#):
>
> I don’t know what’s wrong with using the old full screen rendering to picking Texture.

Some context:

> <https://github.com/mrdoob/three.js/pull/15194>
>
> There's no reason to make a giant render target. For picking we're only going to… read a single pixel so we can setup the camera so the math works out and just render that 1 pixel.
> 
> The main difference in this code vs the current GPU picking example is (a) make 1x1 pixel render target and then set the view offset when rendering the pick scene. Then read that 1x1 pixel
> 
> \`\`\`js
> // set the view offset to represent just a single pixel under the mouse
> 
> camera.setViewOffset( renderer.domElement.width, renderer.domElement.height, mouse.x \* window.devicePixelRatio | 0, mouse.y \* window.devicePixelRatio | 0, 1, 1 );
> camera.updateProjectionMatrix();
> 
> // render the scene
> 
> renderer.render( pickingScene, camera, pickingTexture );
> 
> // clear the view offset so rendering returns to normal
> 
> camera.clearViewOffset();
> camera.updateProjectionMatrix();
> 
> // create buffer for reading single pixel
> 
> var pixelBuffer = new Uint8Array( 4 );
> 
> // read the pixel
> 
> renderer.readRenderTargetPixels( pickingTexture, 0, 0, 1, 1, pixelBuffer );
> \`\`\`
> 
> Because the renderer might a device pixel ratio set we have to also put the mouse in that same range

---

<div class="post-metadata">

**Author:** ![pbeshai](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pbeshai/32/18974_2.png) [@pbeshai](https://discourse.threejs.org/u/pbeshai)\
**Post date:** [June 16, 2021, 9:23pm UTC](https://discourse.threejs.org/t/three-points-use-gpu-picking-is-not-work/9045/7 "2021-06-16T21:23:48Z")

</div>

Just want to chime in here with a couple observations from my own experimentation with GPU picking with THREE.Points.

1. The Points object autoscales the point size based on the height of what’s being drawn, see `refreshUniformsPoints` in WebGLMaterials.js. When you reduce the target to a 1px by 1px size, it messes up the size of the points you’re drawing and you likely won’t see it, hence a miss. You can try and correct this by adjusting the size uniform when picking, but it’s not enough to get it to work (see #2).

2. Additionally, it’s my experience that when the center of a point is off canvas, the entire point doesn’t get drawn. Say you had point size \> 1. If a point was at [-1,-1] you wouldn’t see it rendered at all, but if it were at [0,0] you would. This means that when you zoom into a 1px by 1px size, unless you are focused exactly on the middle of the point, your point won’t render and it will be a miss.

It seems the simplest solution is to just draw the full size screen in the picking texture as Douglas Duhaime’s block above does, this will ensure you’re picking from the same points as what the user sees on screen, even if it is more expensive.
