二维光线跟踪器的算法

我想用Java编写一个程序化的RayTracer用于演示目的,同时提供有关Ray Tracing的演示文稿(也提到3D,这个2D模型应该只是为了更容易理解,并培养我的一般Java知识)。

我的问题是,我不知道从哪里开始这整个事情。

我要尝试的第一件事是使用向量来跟踪给定坐标(例如我的鼠标光标的位置)的屏幕上的每个像素。 然后我会计算向量是否与多边形相交,然后我会在那里停止向量并仅将它绘制到这个特定点。

也许我甚至可以通过计算法线来绘制一些阴影,并以较低的强度reflection另一个方向的矢量。

那么从A = {everypixelonthescreen}绘制一个向量到特定的Point P并计算交叉Point P是一个好主意吗?

完成的版本应该看起来像这样:

在此处输入图像描述

我担心你提出的这种光线跟踪应用程序会比使用真正的3D光线跟踪器更具误导性。

  • 二维光线跟踪器的使用方式略有不同
  • 这可能会让你的观众感到很困惑

我会尝试选择更多本机2D光线跟踪用法,如:

  1. 光学模拟

    这用于模拟镜头和镜子光学器件。 这里来自我的古代2D射线追踪模拟之一的图像:

    光学SIM卡

    1. 存储你的世界

      你有镜头forms的折线+衍射指数和镜子也作为折线。 你有世界衍射指数

    2. 从光源投射R,G,B射线

      仅投出重要的或全部。 使用Snell定律来模拟光学

    如您所见,色度误差是可见的(每种颜色都有自己的波长,因此衍射指数不同)。 您还可以使用MultiBand渲染 。

    如果您添加了Optic Lab的 拖放function,我用这个来调整自定义光学系统

  2. Wolfenstein演示

    这个伪3D游戏使用2D射线投射引擎见维基:Wolfenstein_3D_engine 。 此图片来自此链接:

    wolf3d

    1. 首先绘制地板和天花板/天空为2半屏幕(屏幕除以地平线)
    2. 然后你得到你的迷宫/世界的2D地图(右)

      因此,从所有可见方向的当前位置投射光线(类似于您的图像,但通常使用60度视图)。 必须以子像素(单元)精度完成光线。 光线撞击墙壁(在地图上)获取子像素(单元格)位置。 它表示墙壁纹理的哪个部分被击中

    3. 为每次射击命中在屏幕上绘制适当的列(垂直线)

      它的大小和比例由射线起点的距离决定。 如果我的记忆服务是通过仅使用垂直距离(乘以cos(ray_angle-player_angle) )来完成鱼眼校正。

    这里是我刚刚为了好玩而破坏的例子:

    我的Wolf3D

    它是在C ++中使用纯GDI(仅使用位图扫描线)完成的,根本没有其他第三方库。 它使用单一纹理,漫射+环境照明,2D光线投射。 有2个位图(屏幕,纹理图集)和单个2D地图。 代码小于9 KB,包括rems。 它仅由键盘控制(鼠标用于编辑地图子窗口中的迷宫)。

    这里有动画GIF示例:

    Wolf3D

    如果您有兴趣,请参阅相关的质量保证:

    • 具有可变高度细胞的Wolfenstein

据我了解,这个问题的处理方式不同。 给定一些位置(鼠标的当前位置或类似的东西),将在某个给定角度的范围内跟踪环境(如90度,在您的图片中看起来像360度)。 在所需的角度分辨率中,来自初始位置的光线与所提到的多边形相交。 渲染最近的交叉点。 这种方法应该呈现从给定位置“可见”的点。