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

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

问题描述

我创建了3D光学流动画,其中照相机向球体移动(如



为了清楚起见,您可以在此处

解决方案

如果重新创建球体,则必须生成随机的x和y坐标,初始范围为-25.0到25.0。但是,您必须按到相机的相对距离缩放坐标( 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

分别

 如果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






当然,这不能完全解决您的问题。条件 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天全站免登陆