0

我正在尝试使用 Metal 编写蒙特卡洛路径跟踪器。我让整个管道(几乎)正常工作。我有一些奇怪的条带问题,但这似乎与我的路径跟踪逻辑有关,而不是与金属有关。

对于可能没有使用路径跟踪器经验的人来说,它的作用是从相机生成光线,在给定深度(在我的情况下为 8)的随机方向上围绕场景反弹,并且在每个交叉点/反弹时,它都会遮蔽射线与该材料的颜色。最终目标是通过一次又一次地平均多次迭代来“收敛”成一个非常漂亮和干净的图像。在我的代码中,我的金属计算管道一遍又一遍地运行,管道代表一个迭代。

我构建计算管道的方式是使用以下阶段:

  • 生成光线

  • 循环 8 次(即反弹光线 8 次):

    1 - 计算光线交点并将其从该交点反弹(重新计算方向) 2 -color基于该交点“着色”光线

  • 通过获取当前纹理缓冲区的颜色,将其乘以iteration然后将光线的颜色添加到其中,然后除以 来获取所有迭代的平均值iteration+1。然后将新的存储combined_color在相同的确切缓冲区位置。

因此,在更高的层次上,我的整个Renderer工作是:

1 - 在计算着色器中进行一堆光线计算 2 - 更新缓冲区(这是MTKView的可绘制对象)

问题在于,由于某种原因,我的纹理在 3 个不同级别的颜色累积之间循环,并且在不同颜色之间不断出现故障,就好像有三个不同的程序试图写入同一个缓冲区一样。这不可能是由于竞争条件,因为我们正在从同一个缓冲区位置读取和写入,对吧?这怎么可能发生?

这是我前几次迭代的系统跟踪:

系统跟踪概述

如您所见,在最初的几次迭代中,由于某种原因它不会渲染任何东西,而且速度非常快。我不知道为什么会这样。然后,迭代非常慢。这是第一部分的特写: 系统跟踪特写

我试过每次只输出一个迭代的颜色,看起来非常好。我的图片没有收敛到干净的图像(这是多次迭代平均后发生的情况)

我尝试过使用信号量来同步事物,但我最终得到的只是一个停滞的程序,因为我一直在等待命令缓冲区,并且由于某种原因它永远不会准备好。我想我可能只是没有得到信号量。我试过查资料,我似乎做得对。

帮助..我已经在这个错误上工作了两天。我无法修复它。我什么都试过了。我只是不够了解,甚至无法开始辨别问题。这是该项目的链接。系统跟踪文件可以在System Traces/NaiveIntegrator.trace. 我讨厌只粘贴我的代码,而且我知道 SO 不建议这样做,但问题是我只是不知道错误可能在哪里。我保证一旦问题得到解决,我将在此处粘贴相关的代码片段。

如果你运行代码,你会看到一个简单的康奈尔盒子,中间有一个黄色的球体。如果您让代码运行一段时间,您会看到循环中的第三个图像最终会收敛到一个像样的图像(忽略可能无关紧要的地板上的条带效应)。但问题是图像在 3 个不同的图像之间不断闪烁。

4

0 回答 0