渲染无限大的平面

Vio*_*nev 13 opengl rendering linear-algebra plane

我想渲染一个平面,使它看起来好像在所有方向上都是无限的.我希望远处的飞机边界成为地平线.

使用简单的网格不起作用 - 计算机无法渲染无限多个三角形.即使这是可能的,相机平截头体也会切出远处的多边形并在平面边界和地平线之间产生间隙.

解决方法是以数学方式计算地平线:在平面上找到点,这些点也位于无穷远处的平面上.连接这些点和视口的两个角会创建一个代表所寻找平面的梯形.但是,通过这种方式,飞机无法正常点亮,或应用纹理,或其他需要精细三角测量的东西......

com*_*orm 18

您可以使用标准光栅化管道绘制无限平面.它使用的齐次坐标可以表示"理想"点(也称为无穷点处的消失点或点),就像常规欧几里德点一样快乐,同样设置一个将远平面置于无穷远处的投影矩阵也是完全可行的.

一个简单的方法是每个象限使用一个三角形,如下所示:

vertices [x,y,z,w], for drawing an (x,y) coordinate plane, at (z==0):
  0: [ 0, 0, 0, 1 ]
  1: [ 1, 0, 0, 0 ]
  2: [ 0, 1, 0, 0 ]
  3: [-1, 0, 0, 0 ]
  4: [ 0,-1, 0, 0 ]

draw 4 triangles using indices:
  (0,1,2); (0,2,3); (0,3,4); (0,4,1)
Run Code Online (Sandbox Code Playgroud)

如果你想要一个测试模式(比如无限棋盘),你将不得不处理这样一个事实:将三角形拉伸到无穷大会扭曲任何标准纹理.但是,您可以编写一个像素着色器,根据实际的3D点(即使用xy从世界空间(x,y,z)坐标)确定颜色,完全忽略(扭曲的)纹理坐标.

您可以根据奇偶校验(对于棋盘)选择两种常量颜色,或者通过基于所选坐标的小数部分对其进行采样来平铺纹理.


请注意,对于x,y和z中的每一个,OpenGL的剪辑空间都是[-1..1].您可以通过评估限制来计算适当的投影矩阵,直到剪辑距离f无限制地增加:

clip coords: [x]  =  [ n/r             ]  * view coords [x]
             [y]     [     n/t         ]                [y]
             [z]     [          -1 -2n ]                [z]
             [w]     [          -1   0 ]                [w]
Run Code Online (Sandbox Code Playgroud)

其中(如在链接中): n是近剪裁平面,r是近剪裁平面处平截头体宽度的t一半,并且是近剪裁平面处平截头体高度的一半.

我没有测试过上面的矩阵,所以你付出的代价是值得的.还要注意,当您接近无穷大时,深度值将失去其精度......

虽然,更近距离的精度可能很好 - 例如,在任何给定距离,(近:无穷大)情况下的深度分辨率应比(近:远)比率的情况小约10%. (1:10).