В SDF-мире вся геометрия — это функции расстояния. Объединение двух объектов?
min(a, b). Ставите две сферы рядом, берёте min — и получаете не каплю, а два камня, лежащих друг на друге. Жёсткий стык, шов на пиксель.А хочется ртути. Слизи. Жидкого золота. Капли воды, которая стекает и сливается с другой. Нужно мягкое объединение.
Собственно, вот оно — polynomial smin:
float smin(float a, float b, float k) {
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
return mix(b, a, h) - k * h * (1.0 - h);
}
k — ширина шва. k=0 — жёсткое объединение, обычный min. k=0.3 — между сферами протягивается перешеек. k=1 — две сферы превращаются почти в каплю.Эта формула везде, где в кадре что-то текучее: лава и слизь во многих играх, любая «жидкая» геометрия в шейдерных демосценах. Конечно же, в больших AAA-катсценах жидкость чаще пекут в alembic-кэш — но это уже не процедурка, а проигрывание заранее посчитанной симуляции. У smin своя ниша.
smin выигрывает у alembic-кэшей везде где что-то меняется от ввода игрока в реальном времени. Боссы-слизни, которые делятся и сливаются. Кровь и слизь, динамически стекающиеся в лужи под ногами. Терраморфинг от взрывов, налипание снега. Жгуты энергии из руки игрока к цели. Запечённую симуляцию тут не подсунешь — форма зависит от того, что игрок делает прямо сейчас. А smin честно считает её на лету.
Основная проблема SDF и Raymarching — это производительность. И это главная причина почему SDF не вытеснили полигоны. Но с нынешними мощностями устройств эти техники применимы «локально». Когда полученная ими визуализация композится в сцену. Например, VFX заклинания или какие-то отдельные эффекты.
#мат_геймдев #МатРазбор #шейдеры
