Pull to refresh

Comments 6

Первый раз вижу, чтобы раннюю валидацию и избегание дублирования bounds check преподносили как какое-то откровение...

ибо внутри цикла reflect и add их больше нет.

Как же нет, у вас там std::max(0.0f, formFactor) внутри, любой std::max это условный переход. Сами же говорите про вызовы валидированных типов и сами же это нарушаете.

Зачем вообще делать std::max с нулём для отбрасывания незначащих малых отрицательных чисел, std::fabs быстрее. https://godbolt.org/z/hbh34zG5d (опуская -ffast-math пока что)

Ну и для кода, думающего о низкоуровневой оптимизации, суммирование sumIncoming очень подозрительное, в цикле sumIncoming переприсваивается значение много раз на основе предыдущего значения, очень похоже на "алгоритм маляра Шлемиэля".

Спасибо, что прочитали мою статью и за внимательный разбор кода! Позвольте ответить.

  1. По поводу std::max и условных переходов. Ну вот например, на архитектуре x86 (начиная с SSE) и даже на моем FX-9590 современные компиляторы разворачивают std::max в инструкцию MAXSS / MAXPS. Это branchless операция, она не создает никаких "пузырей" в конвейере, в отличие от реального if. Поэтому производительность здесь не страдает.

  2. Ну и по поводу std::fabs. В задаче Radiosity использование модуля (fabs) физически некорректно. Отрицательное значение (ошибка интегрирования) - это отсутствие света (0), а не "положительный свет". fabs превратит ошибку -0.1 в энергию +0.1, нарушив закон сохранения энергии (создаст свет из ниоткуда). Клампинг к нулю здесь - единственно верное решение.

  3. Насчет нарушения философии. Тут вы абсолютно правы. Валидация formFactor внутри reflect - это компромисс, который я допустил, и сделал это зря. В следующем коммите я вынесу это в отдельный тип FormFactor (как сделано для SpectralEnergy), чтобы ядро функции осталось чистым fmul и философия "валидации на входе" соблюдалась строго.

Большое спасибо за указание в правильную сторону. =)

Максимальный предел отражения света 99.9999% достигнут в лаборатории CNRS

Более чем справедливое замечание. Действительно, в лабораторных условиях (например, в лазерных резонаторах или экспериментах CNRS) существуют метаматериалы и сверхчистые зеркала с коэффициентом отражения, близким к единице.

Однако. Если рассматривать их в контексте Radiosity как Global Illumination, то использование таких значений превращается в этакую "световую бомбу". Проблемы тут вот какие:

  1. Сходимость. Если альбедо близко к 1.0, энергия в системе практически не затухает. Численному решателю потребуются тысячи итераций, чтобы "успокоить" свет, что для реалтайма неприемлемо в принципе.

  2. Ошибка float. На 50-м отскоке погрешность float может случайно превратить 0.999999 в 1.000001, и мы получим генерацию энергии из ниоткуда. В итоге, мы увидим что-то вроде ядерного взрыва в шейдере.

Ограничение 0.95 в H24 тут служит как своеобразный инженерный предохранитель. Мы строим не симулятор лазерной лаборатории, а стабильный графический движок для реалтайма. Для 99% реальных материалов (камень, дерево, ткань, кожа) альбедо редко превышает 0.8-0.9, так что 0.95 - это безопасный потолок, гарантирующий, что свет когда-нибудь затухнет, и картинка стабилизируется.

А можно ли где-нибудь код посмотреть? Я, конечно, в самом начале освоения графики (буквально в самом), но всё рано интересно посмотреть на работы, уже состоятельные в той или иной степени.

Приветствую в рядах графических программистов! Путь предстоит долгий, однако невероятно интересный.

Движок MagnaVerse пока находится в стадии активного R&D (исследований и разработки), это своего рода "лабораторный стенд", поэтому полного исходного кода в открытом доступе нет - там слишком много экспериментальной математики, которая меняется каждый день.

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

Однако код, приведенный в статье (структуры H24) - это абсолютно рабочий "боевой" фрагмент. Вы можете смело брать эти структуры (SpectralEnergy, ValidatedMaterial) и пробовать внедрять их даже в свои первые проекты на OpenGL/Vulkan/DirectX. Это хороший фундамент, чтобы сразу приучить себя к культуре типов.

Успехов в освоении! Если возникнут вопросы по математике - спрашивайте.

Sign up to leave a comment.

Articles