我很久以前就正确解决了这个问题,但直到现在才抽出时间来更新答案。我删除了之前不正确的答案(它给出了几乎正确的结果,但通过间接方法,由于我对问题的根本原因缺乏了解)。
正如 Sam 在之前的评论中提到的,问题的根本原因是,如果您想实现等距列(这对于渲染结果看起来不失真是必要的),固定角度增量实际上是不正确的。这个在论坛帖子里提到过here,但是尽管我发现了这一点,但直到很久以后我才完全理解为什么会出现这种情况,或者如何解决这个问题。
为了在屏幕上实现等距的列,按理说,每条光线必须从视点出发并穿过沿投影表面等距分布的像素,这意味着随着光线远离投影面的中心像素,在屏幕上,与观看方向的角度增加的增量逐渐变小。下图说明了这一点(抱歉,这不完全是一件艺术品):
对于较小的视场,问题不是很明显,但随着视场的增加,问题变得更加严重(在我的图中,视场相当大,可以清楚地说明问题)。为了正确计算光线角度增量,必须使用以下过程:
Where:
ang = ray angle from the look direction, whose ray passes through the central x coordinate of the screen;
opp = opposite side (equivalent to the distance of the screen X coordinate through which the ray passes from the screen X coordinate of the central pixel);
adj = adjacent side (equivalent to the distance from the point of view to the projection surface, which will be predetermined in code somewhere);
我们可以使用以下公式(为了清楚起见,包括推导):
tan( ang ) = opp / adj
ang = atan( opp / adj )
ang = atan( ( pixel x coord - half screen width ) / dist to projection surface )
我的引擎中的 Javascript 代码示例:
for( var x = 0; x < canvasSizeX; x++ ){
var xAng = _atan( ( x - canvasSizeHalfX ) / m_DistToProjSurf );
xRayAngles.push( xAng );
}
由于在线提供的有关光线投射引擎的信息有些稀缺,而且由于任何主要教程都没有明确涵盖这个特定问题,我想用正确的内容更新这篇文章信息以防其他人遇到与我相同的问题并且不明白原因。希望这会对某人有所帮助。