在 3D 动画中,在相机前保持恒定数量的可见球体 [英] Keep constant number of visible spheres in front of the camera in 3D animation

查看:20
本文介绍了在 3D 动画中,在相机前保持恒定数量的可见球体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个 3D 光流动画,其中相机向球体移动(如图所示

为了清楚起见,您可以在这里找到我的代码

解决方案

如果重新创建球体,则必须生成随机的 x 和 y 坐标,初始范围为 -25.0 到 25.0.但是您必须通过与相机的相对距离 (z/far_z) 来缩放坐标:

如果 sphere.position.z >= camera_z:z_abs = np.random.uniform(camera_z+near_z,camera_z+far_z)sphere.position.z = z_abssphere.position.x = np.random.uniform(-25, 25) * (z_abs-camera_z)/far_zsphere.position.y = np.random.uniform(-25, 25) * (z_abs-camera_z)/far_z

分别

如果 sphere.position.z >= camera_z:z_rel = np.random.uniform(near_z, far_z)sphere.position.z = z_rel + camera_zsphere.position.x = np.random.uniform(-25, 25) * z_rel/far_zsphere.position.y = np.random.uniform(-25, 25) * z_rel/far_z

<小时>

当然,这不会完全解决您的问题.条件 sphere.position.z >= camera_z 处理通过近平面离开视域的球体.在透视投影中,视图体积是一个 Frustum.有一些球体在视锥体的侧面(在窗口的侧面)离开了视野.
要解决这个问题,您需要第二个条件,并且必须考虑球体到视图中心的最大距离:

max_dist = max(abs(sphere.position.x), abs(sphere.position.y))limit_dist = 25 * abs((sphere.position.z-camera_z)/far_z)如果 sphere.position.z >= camera_z 或 max_dist >limit_dist:# [...]

I created a 3D optic flow animation, where a camera moves towards spheres (as shown here ). I would like to keep the same number of visible spheres in front of the camera, that way, while the camera moves towards them, and when a sphere is behind the camera, another sphere is drawn in front of the camera. To do so:

  • The initial coordinates x,y,z of each sphere is generated:

     near_z = -10.0;
     far_z = -50.0;
     nSpheres = 8;
    
    for sphere in spheres:
        sphere.position.xy = np.random.uniform(-25, 25, size=2)
        z = np.random.uniform(near_z, far_z)
    
        sphere.position.z = z
        sphere.position.x *= z/far_z
        sphere.position.y *= z/far_z
    

  • Then within the loop that creates the animation and updates the position, there is a condition that keeps a constant number of spheres in front of the camera: every time one disappears, it should calculate the coordinates of a new one in front of the camera.

    while 1:
    
    
     with shader:
    
       # Move the camera towards the spheres
       camera_z -= .6
    
       transformations['view_matrix'] = get_view_matrix(z=camera_z)
       transformations.send()
    
    
       for sphere in spheres:
           sphere.draw()
    
        # If a sphere is behind a camera, generate new sphere coordinates, with the z from the camera to z_far.This way we keep a constant number of visible spheres.
    
           if sphere.position.z >= camera_z:
    
             sphere.position.z = np.random.uniform(camera_z+near_z, camera_z+far_z)
             sphere.position.x = np.random.uniform((sphere.position.z-camera_z)/far_z)
             sphere.position.y = np.random.uniform((sphere.position.z-camera_z)/far_z)
    

As you can see in the GIF below, there seem to be 2 phases:

First, the spheres are randomly and uniformly distributed in the screen, and disappear behind the camera when it passes by. But no new sphere is created when one disappears (the condition in the loop above doesn't seem to work in the beginning).

Then starts a series of spheres appearing when another disappears (due to the condition in the loop) but the new spheres are always coming from the centre and following the same path. Therefore, they are not generated randomly and distributed uniformly in the screen.

For the sake of clarity, you can find my code here

解决方案

If you recreate the spheres, the you've to generate random x and y coordinates the initial range from -25.0 to 25.0. But you've to scale the coordinates by the relative distance to the camera (z/far_z):

if sphere.position.z >= camera_z:

    z_abs = np.random.uniform(camera_z+near_z, camera_z+far_z) 
    sphere.position.z = z_abs 
    sphere.position.x = np.random.uniform(-25, 25) * (z_abs-camera_z)/far_z
    sphere.position.y = np.random.uniform(-25, 25) * (z_abs-camera_z)/far_z

respectively

if sphere.position.z >= camera_z:

    z_rel = np.random.uniform(near_z, far_z) 
    sphere.position.z = z_rel + camera_z
    sphere.position.x = np.random.uniform(-25, 25) * z_rel/far_z
    sphere.position.y = np.random.uniform(-25, 25) * z_rel/far_z


Of course this won't solve your issue completely. The condition sphere.position.z >= camera_z handles the spheres which leave the view volume through the near plane. At perspective projection the view volume is a Frustum. There are spheres which leave the view at the sides of the frustum (at the sides of the window).
To handel this you'll need a 2nd condition and you've to take into account the maximum distance of a sphere to the center of the view:

max_dist   = max(abs(sphere.position.x), abs(sphere.position.y))
limit_dist = 25 * abs((sphere.position.z-camera_z) / far_z)

if sphere.position.z >= camera_z or max_dist > limit_dist:

    # [...]

这篇关于在 3D 动画中,在相机前保持恒定数量的可见球体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆