金属纹理以非常奇怪的方式更新

时间:2017-11-24 03:54:10

标签: c++ gpu metal raytracing mtlbuffer

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

对于那些可能没有路径追踪经验的人来说,它所做的就是从相机中产生光线,在给定深度(在我的情况下为8)的每个交叉点/反弹的随机方向上围绕场景反弹它用这种材料的颜色遮住光线。最终目标是让它“收敛”#34;通过一遍又一遍地平均多次迭代来获得非常漂亮和干净的图像。在我的代码中,我的金属计算管道一次又一次地运行,管道代表迭代。

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

  • 生成光线

  • 循环8次(即将光线反射8次左右):

    1 - 计算光线交叉点并将其从该交叉点反弹(重新计算方向) 2 - " Shade"基于该交叉点的光线color

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

所以我的整个combined_color所做的更高层次是:

1 - 在计算着色器中进行一堆光线计算 2 - 更新缓冲区(Renderer'可绘制的)

问题是由于某种原因,我的纹理会在3种不同的色彩累积水平之间循环,并在不同颜色之间保持毛刺,几乎就像有三个不同的程序试图写到同一个缓冲区。这可能是由于竞争条件造成的,因为我们正在从相同的缓冲区读取和写入对吗?怎么会发生这种情况?

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

System Trace Overview

正如您所看到的,对于前几次迭代,由于某种原因它不会渲染任何东西,并且它们超级快。我不知道为什么会这样。然后,迭代非常慢。以下是第一部分的特写: System Trace Close-up

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

我尝试使用信号量来同步事物,但我最终得到的是一个停滞的程序,因为我一直在等待命令缓冲区,并且由于某种原因它从未准备好。我想我可能不会得到信号量。我已经尝试过了,我似乎正在做正确的事。

帮助 ..我已经在这个bug上工作了两天。我无法修复它。我尝试了一切。我只是不知道甚至开始辨别问题。 Here is a link to the project。系统跟踪文件可以在MTKView下找到。我不想只是粘贴我的代码,我理解这不推荐在SO,但问题是我只是不知道bug可能在哪里。我保证,一旦问题得到解决,我就会在此处粘贴相关的代码段。

如果你运行代码,你会看到一个简单的cornell box,中间有一个黄色球体。如果你让代码运行一段时间,你会发现周期中的第三个图像最终收敛到一个像样的图像(忽略了可能无关的地板上的条带效果)。但问题是图像在3个不同的图像之间保持闪烁。

0 个答案:

没有答案