Уменьшение изменяемого общего состояния

Итак, я прохожу учебник по трассировке лучей в попытке растянуть мои ноги F#. Поскольку учебное пособие написано на C++, выяснить, как применять концепции функционально, довольно сложно. Я хотел бы написать все настолько функционально, насколько это возможно, потому что я намерен в конечном итоге запустить трассировщик лучей параллельно. Но это привело меня к следующей ситуации, суть которой, я уверен, проявляется в других вопросах, помимо трассировки лучей.

У нас есть Engine объект, который (среди прочего) хранит Scene объект (коллекция Primitive объекты). В настоящее время Scene и Primitives в нем полностью неизменны.

Чтобы попытаться улучшить время рендеринга, мы реализуем обычную трехмерную сетку. Чтобы эффективно пройти по сетке, учебник ссылается на эту статью как для алгоритма обхода, так и для уменьшения количества тестов пересечения для примитивов, которые лежат за границами сетки. Вот как работает последняя часть:

  • каждый Ray назначен уникальный rayID
  • каждый Primitive имеет lastRayID поле.
  • Когда Ray проверяет пересечение с Primitive,
    1. Если rayID из Ray равно lastRayID из Primitive, тогда тест пересечения пропускается.
    2. В противном случае выполняется тест, и rayID из Ray хранится в lastRayID поле Primitive,

Это аккуратный способ кэширования тестов пересечений, но он настроен на последовательный трассировщик лучей и не будет работать вообще даже для двух одновременных лучей. Поэтому, хотя я мог бы использовать mutable поля, и, следовательно, быть в состоянии реализовать этот алгоритм, это не будет удовлетворять мои конечные цели по сути параллелизуемым трассировщик лучей.

У меня есть одна идея. Проблема с хранением изменяемого состояния с каждым примитивом состоит в том, что в отношении алгоритма рендеринга сцена является глобальной сущностью - каждый луч может потенциально ударить любой примитив. С другой стороны, каждый луч полностью автономен. Таким образом, в каждом луче я полагал, что мог бы создать набор примитивов, которые уже были проверены (этот набор будет эквивалентен lastRayID поле описано выше). Проблема заключается в том, что каждый луч имеет чрезвычайно короткий срок службы, и потенциально может существовать много лучей в любой момент времени, поэтому установка такой структуры данных в каждом луче может быть дорогостоящей ((де) выделять время и память Расходы на потребление могут сложиться быстро)

У кого-нибудь есть советы по работе с подобными ситуациями? Даже если это общая идея о преобразовании общего изменяемого состояния в локальное изменяемое состояние или что-то подобное, я уверен, что это мне очень поможет. Я был бы рад уточнить что-нибудь, если это необходимо.

0 ответов

Другие вопросы по тегам