2D光线追踪算法

6
我想为演示目的在Java中进行编程的RayTracer,同时讲述射线追踪的概念(也提到3D,但这个2D模型只是为了更容易理解和培养我的Java知识)。
我的问题是,我不知道从哪里开始。
首先,我会尝试使用向量来跟踪屏幕上每个像素,从给定坐标(例如,我的鼠标光标位置)开始。然后,我会计算向量是否与多边形相交,然后我会在那里停止向量并仅将其绘制到此特定点。
也许我甚至可以通过计算法线并将向量反射到另一个方向来绘制一些阴影,并降低强度。
所以,从A = {屏幕上的每个像素}到特定点P绘制向量并计算交点是一个好主意吗?
最终版本应该看起来像这样:

enter image description here

2个回答

14

恐怕您所提出的射线追踪应用程序有点比使用真正的3D射线追踪器更具误导性。

  • 2D射线跟踪器的使用方式略有不同
  • 这可能会让您的观众感到困惑

我建议选择更本地的2D射线跟踪使用方式,例如:

  1. 光学模拟

    用于模拟透镜和镜子光学原理。下面的图片是我古老的2D射线跟踪模拟之一:

    optic sim img

    1. 储存你的世界

      你有由折射率和镜子组成的透镜形状。你可以得到整个世界的折射率

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

      只投射重要的或全部。使用斯涅尔定律模拟光学原理

    如您所见,色差是可见的(每种颜色都有自己的波长,因此折射率不同)。您还可以使用多波段渲染

    我用它来调整自定义光学系统。如果增加拖放功能,您就有了Optic Lab

  2. Wolfenstein演示

    这个伪3D游戏使用了2D射线投射引擎。请参阅维基:Wolfenstein_3D_engine。这张图片来自于该链接:

    wolf3d

    1. 首先将地板和天花板/天空绘制为两个半屏幕(由视野线分割成两半)
    2. 然后你就有了迷宫/世界的二维地图(右图)

      从当前位置向所有可见方向投射光线(类似于您的图片,但通常使用60度视野)。光线必须使用亚像素(单元格)精度进行操作。光线在地图上碰到墙壁时,获得亚像素(单元格)位置。这表明撞到了哪部分墙壁贴图

    3. 为每条光线碰撞处在屏幕上绘制相应的列(竖线)

      其大小和比例由光线起点到碰撞处的距离决定。鱼眼校正被应用 - 如果我没记错,它是通过仅使用垂直距离来完成的(将距离乘以 cos(ray_angle - player_angle) )。

    这里是我现在闲暇时制作的一个示例:

    my Wolf3D

    使用纯GDI(仅使用位图扫描线),没有其他第三方库,用C++编写。它使用单一纹理、漫反射+环境照明、2D光线跟踪。有两个位图(屏幕、纹理集)和单个2D地图。代码包括rems不到9 KByte。它只能通过键盘控制(鼠标用于在地图子窗口中编辑迷宫)。

    下面是一个动画GIF示例:

    Wolf3D

    如果您感兴趣,请查看此相关QA:


@Einstein 请参考GLSL中的2D射线投影光效果 - Spektre

0
据我理解,这个问题的处理方式会有所不同。给定某个位置(鼠标的当前位置或类似的位置),从那里开始在一定角度范围内(比如90度,在你的图片中看起来像360度)跟踪环境。在所需角度的分辨率下,从初始位置发出的射线与提到的多边形相交。最近的交点被渲染出来。这种方法应该可以渲染出从给定位置“可见”的点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接