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