Если сцена не полностью помещается в память, вы попадаете в область рендеринга вне ядра. Здесь есть два основных подхода: а) создать сцену по запросу; б) загрузить сцену по запросу.
Первый подход хорошо согласуется с большинством рабочих процессов анимации, где модели в значительной степени подразделяются с использованием, например, Catmull-Clark, и могут сильно загружать память, но сами базовые сетки легко помещаются в память. У Pixar есть несколько статей об этом (например, кэширование разностей лучей и геометрия многоразрешающей геометрии для трассировки лучей распределения в сложных сценах ), но суть в том, что модели подразделяются только тогда, когда на них воздействует луч, и подразделяются только на столько, сколько есть. разумно для такого луча (например, диффузное взаимное отражение требует меньшей точности, чем зеркальное отражение). Остальное обрабатывается кешем геометрии, который хранит разделенные модели в памяти и, как мы надеемся, делает процесс эффективным благодаря хорошей стратегии выселения.
Пока все ваши базовые сетки удобно помещаются в памяти, вы можете легко выходить из ядра и рендерить сетки на уровнях подразделений, которые никогда не поместятся в память. Кэш геометрии также хорошо масштабируется с объемом имеющейся у вас памяти, что позволяет вам сравнивать оперативную память с временем рендеринга. Это также использовалось в автомобилях, я верю.
Второй подход носит более общий характер и не опирается на интенсивное использование подразделения. Вместо этого он опирается на тот факт, что ваша сцена, скорее всего, была сделана художником и уже разделена на достаточно маленькие объекты, которые индивидуально вписываются в память. Идея состоит в том, чтобы сохранить две иерархии (иерархию kD-деревьев или ограничивающих томов): иерархию верхнего уровня, которая хранит только ограничивающие блоки объектов в вашей сцене, и иерархию низкого уровня, в которой хранится фактическая геометрия. Существует одна такая иерархия низкого уровня для каждого объекта.
При таком подходе вы в идеале уже сохраняете ограничивающую рамку вместе с каждым объектом на диске. Когда сцена загружена, вы изначально строите иерархию верхнего уровня, то есть вам нужно смотреть только на ограничивающие рамки, а не на геометрию. Затем вы начинаете отслеживать лучи и проходить их через иерархию. Всякий раз, когда луч попадает на листовой узел в иерархии верхнего уровня (т. Е. Он попадает в ограничивающую рамку объекта), этот объект загружается в память и строится его иерархия низкого уровня. Луч затем продолжает прослеживать этот объект. В сочетании с объектным кешем, который сохраняет в памяти как можно большую часть низкоуровневой иерархии, он может работать достаточно хорошо.
Первое преимущество такого подхода заключается в том, что объекты, которые никогда не попадают, никогда не загружаются, а это означает, что он автоматически адаптируется к видимости вашей сцены. Второе преимущество заключается в том, что если вы отслеживаете много лучей, вам не нужно сразу загружать объект, поскольку он попадает под луч; вместо этого вы можете удерживать этот луч и ждать, пока достаточное количество лучей достигнет этого объекта, амортизируя нагрузку в результате нескольких попаданий лучей.
Вы также можете комбинировать этот подход с алгоритмом сортировки лучей, таким как Sorted Deferred Shading для трассировки производственных путей, чтобы избежать сбоев из-за некогерентных лучей. Упомянутая статья описывает архитектуру рендерера Hyperion Диснея, который, как я полагаю, использовался для Big Hero 6, поэтому он, скорее всего, может обрабатывать сцены в производственных масштабах.