I have generated an optic flow animation, with spheres (circles) that move towards the viewer in a 3D coordinates space. For some reason, although I define a number of 8 spheres, it never displays all the spheres every time I run the code; sometimes it displays 1, sometimes 4 (like in the gif). It is eventually a random number of spheres from 1 to 8.
My code is available on Github
At perspective projection, the viewing volume is a frustum. So probably the spheres are clipped (not in the frustum) at the sides of the frustum, especially when they are close to the near plane.
Note, most of the stars "leave" the window at its borders, when they come closer to the camera (except the ones, who leave the frustum through the near plane).
Set the initial z-coordinate of the spheres to it's maximum (far plane), for debug reasons:
for sphere in spheres:
sphere.position.xy = np.random.uniform(-25, 25, size=2)
#sphere.position.z = np.random.uniform(0.0, -50.0)
sphere.position.z = 50
If you don't "see" all stars at all, then the range for the x and y coordinate ([-25, 25]) is to large.
To compensate the in initial clipping you can scale the x and y component by the distance:
for sphere in spheres:
sphere.position.xy = np.random.uniform(-25, 25, size=2)
z = np.random.uniform(0.0, -50.0)
sphere.position.z = z
sphere.position.xy[0] *= z/-50
sphere.position.xy[1] *= z/-50