Ray-marching это по сути алгоритм численного интегрирования. В случае облаков в самом простом случае нам необходимо проинтегрировать (просуммировать) плотность (функцию трёх пространственных координат) вдоль луча, исходящего от наблюдателя (камеры) и в зависимости от величины этого интеграла смешать цвет неба с цветом облака. Интегрирование, опять же в самом простом случае, осуществляется методом прямоугольников. Вдоль луча, исходящего из камеры, берётся несколько точек, в которых вычисляется значение плотности и умножается на длину шага. Эти величины складываются и мы имеем приближённое значение интеграла от произвольной функции, заданной в 3д пространстве, вдоль какой-то прямой.
Но обычно это полбеды. Интеграл вдоль луча из камеры позволяет симулировать поглощение в среде, но не рассеяние. Для однократного рассеяния на каждом шаге ray-marching'а необходимо делать аналогичную процедуру в направлении источника света. Для двухкратного: на каждом шаге ray-marching'а делается ray-marching в произвольном направлении, на каждом шаге которого делается ray-marching в направлении источника света. Очевидно, что такая процедура очень быстро становится очень дорогой в плане вычислений, поэтому обычно ограничиваются однократным рассеиванием, а все следующие порядки аппроксимируются каким-то другим образом. На английском языке достаточно много литературы по этому поводу, приведу несколько статей:
https://shaderbits.com/blog/creating-volumetric-ray-marcherhttps://blog.uhawkvr.com/rendering/rendering-volu ... -using-signed-distance-fields/Если есть какие-то конкретные вопросы - с радостью отвечу
В блендере разумеется это делается нодами. Но так как возможности делать циклы автоматически нет, то создаётся группа нод, которая вычисляет один шаг этого алгоритма. Потом произвольное количество этих групп соединяется последовательно для реализации такого же количества шагов алгоритма