Search code examples
pythonanimationopenglpygletpsychopy

Failed to display all the spheres in perspetive projection of 3D animation


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

enter image description here


Solution

  • 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