如果我做对了,您想要渲染一些标记(例如顶点拖动编辑区域),对于它们渲染到的任何深度都具有相同的视觉尺寸。
有两种方法:
随深度扩展
计算与相机视图的垂直距离(简单点积)并缩放标记尺寸,使其具有与深度相同的视觉尺寸不变。
所以如果P0 是你的相机位置,Z是你的相机视图方向单位向量(通常是 Z 轴)。然后对于任何位置P计算比例如下:
depth = dot(P-P0,Z)
Run Code Online (Sandbox Code Playgroud)
现在,比例取决于size0某些指定的所需视觉效果depth0。现在使用三角形相似度我们想要:
size/dept = size0/depth0
size = size0*depth/depth0
Run Code Online (Sandbox Code Playgroud)
size所以用或 scale渲染你的标记depth/depth0。如果使用缩放,您需要围绕目标位置进行缩放P,否则您的标记将移动到两侧(因此平移、缩放、向后平移)。
计算屏幕位置并使用非透视渲染
因此,您可以像图形管道一样变换目标坐标,直到获得屏幕x,y位置。请记住这一点,并且在传递过程中,您的标记将仅使用它而不是真实位置。对于此渲染通道,可以使用一些恒定的深度(距相机的距离)或使用非透视视图矩阵。
有关详细信息,请参阅了解 4x4 齐次变换矩阵
[编辑1]像素大小
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
Run Code Online (Sandbox Code Playgroud)
其中pixelx,pixely是 代表深度处视觉上单个像素的尺寸(每轴)znear。如果展位尺寸相同(因此像素是正方形),您就拥有了所需的一切。如果它们不相等(像素不是正方形),那么您需要在屏幕轴对齐坐标中渲染标记,因此方法#2更适合这种情况。
因此,如果您选择depth0=znear,则可以设置size0为n*pixelx和/或n*pixely获取n像素的视觉大小。或者使用 anydept0并将计算重写为:
pixelx = 2*depth0*tan(FOVx/2)/xs
pixely = 2*depth0*tan(FOVy/2)/ys
Run Code Online (Sandbox Code Playgroud)
只是为了完整:
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
Run Code Online (Sandbox Code Playgroud)