I do picking in the pixel shader that I use to draw my objects, without using an additional pass. My code is dx11 or dx12, but you might be able to employ a similar technique in your language.
I pass an "object number" down from the vertex shader to the pixel shader when i draw my objects.
I send the mouse coordinates to the pixelshader in a cbuffer (its in my cbeveryframe buffer that is updated each frame)
In the pixel shader, if the pixel coodinates are equal to the mouse coordinates, I construct a uint where the high 16 bits are the pixel depth and the low 16 bits are the data to send back, in this case data is the "object number"
I then write this number to a uav buffer using an interlockedmin function.
This causes the closest object at the mouse coordinates to have its "object number" to be written to the uav
Then in the cpu I read this uav buffer (well actually a cpu-map buffer that I copied the uav to), and take the low 16 bits of the uint to get the object number.
I send back various pieces of information about the object under the mouse back to the cpu using this techique by using different uint variables in that uav.buffer.
That pixel shader is also used to draw the object after the above piece of code.
Performance tip when sending things from the gpu to the cpu - dont try to read the same buffer in the cpu imediately after the cpu draw command that causes that buffer to be written by the gpu. Allow it a few frames by for example having 3 uav buffers (and their corresponding cpu-map buffers that they are copied to) that you rotate between.
This is because the draw in the gpu doesnt occur imediately it is issued in the cpu.