Обновление металлической текстуры очень странным образом
Я пытаюсь написать трассировщик Монте-Карло, используя Metal. У меня весь конвейер работает (почти) правильно. У меня есть некоторые странные проблемы с полосами, но похоже, что это больше связано с моей логикой трассировки пути, чем с металлом.
Для людей, которые могут не иметь опыта работы с трассировщиком путей, он генерирует лучи из камеры, направляет ее вокруг сцены в произвольных направлениях на заданную глубину (в моем случае, 8), и на каждом пересечении / отскок он затеняет Луч с цветом этого материала. Конечная цель состоит в том, чтобы он "сходился" к очень красивому и чистому изображению, усредняя много итераций снова и снова. В моем коде мой металлический вычислительный конвейер запускается снова и снова, причем конвейер представляет собой итерацию.
То, как я структурировал мой конвейер вычислений, использует следующие этапы:
Генерировать лучи
Цикл 8 раз (т.е. отскок луча около 8 раз):
1 - вычислить пересечения лучей и отразить его от этого пересечения (пересчитать направление) 2 - "затенить" лучи
color
на основании этого пересеченияПолучите среднее значение всех итераций, получив цвет текущего буфера текстуры и умножив его на
iteration
а затем добавить цвет луча к нему, а затем разделить наiteration+1
, Затем сохраните этот новыйcombined_color
в том же месте буфера.
Так что на еще более высоком уровне, чем весь мой Renderer
делает это:
1 - Выполните кучу вычислений лучей в вычислительном шейдере. 2 - Обновите буфер (который является MTKView
ничья)
Проблема в том, что по какой-то причине происходит то, что моя текстура переключается между 3 разными уровнями накопления цветов и продолжает колебаться между разными цветами, как будто три разные программы пытаются записать в один и тот же буфер. Это не может быть связано с условиями гонки, потому что мы читаем и пишем из одного и того же буфера, верно? Как это может происходить?
Вот мой системный след первых нескольких итераций:
Как видите, за первые несколько итераций он по какой-то причине ничего не рендерит, и они очень быстрые. Я понятия не имею, почему это так. Затем, итерации очень медленные. Вот крупный план этой первой части:
Я пытался выводить только один цвет итерации каждый раз, и это, кажется, прекрасно. Моя картинка не сходится к чистому изображению (что происходит после усреднения нескольких итераций)
Я пытался использовать семафоры для синхронизации вещей, но все, что у меня получается, это зависшая программа, потому что я все еще жду буфера команд и по какой-то причине он никогда не готов. Я думаю, что я просто не получаю семафоры. Я пытался искать вещи, и я, кажется, делаю это правильно.
Помогите.. Я работал над этой ошибкой в течение двух дней. Я не могу это исправить. Я перепробовал все. Я просто не знаю достаточно, чтобы даже начать различать проблему. Вот ссылка на проект. Файл системной трассировки находится в System Traces/NaiveIntegrator.trace
, Я ненавижу просто вставлять свой код, и я понимаю, что это не рекомендуется в SO, но проблема в том, что я просто не знаю, где может быть ошибка. Я обещаю, что, как только проблема будет решена, я вставлю сюда соответствующие фрагменты кода.
Если вы запустите код, вы увидите простую коробку Корнелла с желтой сферой в середине. Если вы оставите код запущенным на некоторое время, то увидите, что третье изображение в цикле в конечном итоге сходится к приличному изображению (игнорируя эффект полос на полу, который, вероятно, не имеет значения). Но проблема в том, что изображение продолжает мерцать между 3 различными изображениями.