不变比例几何

时间:2017-06-05 22:59:26

标签: algorithm opengl geometry directx

我正在编写一个网格编辑器,我在其中有操纵器,我可以帮助改变网格的顶点。任务是渲染具有恒定尺寸的操纵器,这在更改摄像机和视口参数时不会改变。投影矩阵是透视的。我将很感激如何实现不变比例几何的想法。

1 个答案:

答案 0 :(得分:4)

如果我做对了你想渲染一些标记(例如顶点拖动编辑区域),它们具有相同的视觉尺寸,可以渲染它们的任何深度。

有两种方法:

  1. 按深度缩放

    计算与摄像机视图的垂直距离(简单的点积)并缩放标记大小,使其具有相同的视觉大小不变的深度。

    因此,如果P0是您的相机位置,Z是您的相机视图方向单位矢量(通常是Z轴)。然后对于任何位置P计算这样的比例:

    depth = dot(P-P0,Z)
    

    现在,比例取决于指定size0处的所需视觉depth0。现在使用我们想要的三角形相似度:

    size/dept = size0/depth0
    size = size0*depth/depth0
    

    所以使用size或缩放depth/depth0渲染标记。如果使用缩放比例,您需要缩放目标位置P,否则您的标记会移到两侧(因此翻译,缩放,翻译)。

  2. 计算屏幕位置并使用非透视渲染

    因此您可以使用与图形管道相同的方式转换目标坐标,直到获得屏幕x,y位置。记住它并在传递中将使你的标记只使用它而不是真实的位置。对于此渲染过程,要么使用一些恒定深度(距离相机的距离),要么使用非透视视图矩阵。

  3. 有关详细信息,请参阅Understanding 4x4 homogenous transform matrices

    [Edit1]像素大小

    您需要使用FOVx,FOVy投影角度和视图/屏幕分辨率(xs,ys)。这意味着如果深度为znear且坐标为角度的一半,则投影坐标将转到屏幕边缘:

    tan(FOVx/2) = (xs/2)*pixelx/znear
    tan(FOVy/2) = (ys/2)*pixely/znear
    ---------------------------------
    pixelx = 2*znear*tan(FOVx/2)/xs
    pixely = 2*znear*tan(FOVy/2)/ys
    

    其中pixelx,pixely的大小(每个轴)在深度znear处可视地表示单个像素。如果展位尺寸相同(所以像素是正方形),您就拥有了所需的一切。如果它们不相等(像素不是正方形),那么你需要在屏幕轴对齐的坐标上渲染标记,所以接近#2 更适合这种情况。

    因此,如果您选择depth0=znear,则可以将size0设置为n*pixelx和/或n*pixely,以获得n像素的可视大小。或者使用任何dept0并将计算重写为:

    pixelx = 2*depth0*tan(FOVx/2)/xs
    pixely = 2*depth0*tan(FOVy/2)/ys
    

    要完成:

    size0x = size_in_pixels*(2*depth0*tan(FOVx/2)/xs)
    size0y = size_in_pixels*(2*depth0*tan(FOVy/2)/ys)
    -------------------------------------------------
    sizex = size_in_pixels*(2*depth0*tan(FOVx/2)/xs)*(depth/depth0)
    sizey = size_in_pixels*(2*depth0*tan(FOVy/2)/ys)*(depth/depth0)
    ---------------------------------------------------------------
    sizex = size_in_pixels*(2*tan(FOVx/2)/xs)*(depth)
    sizey = size_in_pixels*(2*tan(FOVy/2)/ys)*(depth)
    ---------------------------------------------------------------
    sizex = size_in_pixels*2*depth*tan(FOVx/2)/xs
    sizey = size_in_pixels*2*depth*tan(FOVy/2)/ys