我正在编写一个网格编辑器,我在其中有操纵器,我可以帮助改变网格的顶点。任务是渲染具有恒定尺寸的操纵器,这在更改摄像机和视口参数时不会改变。投影矩阵是透视的。我将很感激如何实现不变比例几何的想法。
答案 0 :(得分:4)
如果我做对了你想渲染一些标记(例如顶点拖动编辑区域),它们具有相同的视觉尺寸,可以渲染它们的任何深度。
有两种方法:
按深度缩放
计算与摄像机视图的垂直距离(简单的点积)并缩放标记大小,使其具有相同的视觉大小不变的深度。
因此,如果P0
是您的相机位置,Z
是您的相机视图方向单位矢量(通常是Z轴)。然后对于任何位置P
计算这样的比例:
depth = dot(P-P0,Z)
现在,比例取决于指定size0
处的所需视觉depth0
。现在使用我们想要的三角形相似度:
size/dept = size0/depth0
size = size0*depth/depth0
所以使用size
或缩放depth/depth0
渲染标记。如果使用缩放比例,您需要缩放目标位置P
,否则您的标记会移到两侧(因此翻译,缩放,翻译)。
计算屏幕位置并使用非透视渲染
因此您可以使用与图形管道相同的方式转换目标坐标,直到获得屏幕x,y
位置。记住它并在传递中将使你的标记只使用它而不是真实的位置。对于此渲染过程,要么使用一些恒定深度(距离相机的距离),要么使用非透视视图矩阵。
有关详细信息,请参阅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