PBR — физически корректный рендеринг
Механизм: почему «физически осмысленные» параметры всё изменили
Проблема до PBR. Материал описывали ad hoc числами: diffuse-цвет, сила бликов, ambient-добавка — и подгоняли на глаз под свет конкретного уровня. Три беды: (1) перенёс объект в другое освещение — блик и яркость поплыли; (2) материалы разных художников не стыковались (каждый тюнил по-своему); (3) ничего нельзя переиспользовать как библиотеку. По сути — «храни сырьё, а не модель» наоборот: куча несвязных подкрученных значений вместо одного физического описания.
Инсайт. Опиши материал тем, что не зависит от сцены — его физикой. Тогда рендер сам посчитает, как он выглядит под любым светом. Стандартный набор (metallic-roughness workflow):
- Albedo (базовый цвет) — какая доля каждой длины волны отражается диффузно (0–1 на канал). Это «цвет краски», без бликов и теней.
- Roughness — шероховатость: 0 = идеальное зеркало, 1 = матовая пыль. Управляет шириной блика: гладкое → острый яркий блик, шершавое → размазанный тусклый.
- Metallic — металл или нет: 0 = диэлектрик (пластик, дерево, кожа: есть и диффуз, и слабый ~4% блик), 1 = металл (диффуза нет вообще, блик цветной — золото отражает жёлтым). Промежуток физически почти не встречается, потому и «почти бинарный».
Микрофасеты — откуда берётся roughness
Шероховатая поверхность вблизи — это мириады крошечных идеальных зеркал (микрофасетов) со случайным наклоном. Roughness — это разброс их ориентаций. Гладкая поверхность: все микрозеркала смотрят почти одинаково → отражённый свет летит узким пучком → острый блик. Шершавая: наклоны разбросаны → свет рассеивается широким конусом → блик размывается и тускнеет. Никакого «нарисованного» блика — он выводится из статистики микрорельефа.
Френель — почему всё на скользящем угле зеркало
Доля отражённого света растёт к скользящим углам: смотри в воду прямо вниз — видишь дно (отражается ~2–4%); посмотри вдоль глади к горизонту — она зеркало (отражается ~100%). Это эффект Френеля, и в реал-тайме его берут приближением Шлика:
где — отражательность в лоб (нормальное падение), θ — угол между взглядом и нормалью. Тут и прячется metallic: у диэлектриков ≈ 0.04 (бесцветные 4%) плюс диффузный albedo; у металлов = их цветной albedo (золото ≈ {1.0, 0.76, 0.34}) и диффуза нет. Поэтому «metallic» переключает, куда уходит albedo: в диффуз (диэлектрик) или в цвет блика (металл).
Сохранение энергии — почему PBR не «светится»
Поверхность не может отразить больше света, чем получила. Старые материалы это нарушали (диффуз + блик могли давать >100%) — отсюда «пластилиновый» или «светящийся» вид. PBR делит бюджет: чем больше уходит в зеркальное отражение (по Френелю), тем меньше остаётся диффузу, и сумма ≤ 1. Это и делает картинку «настоящей» под любым светом, а не только под тем, под который крутили.
Числовой пример — Френель воды
Диэлектрик, = 0.04. В лоб (cos θ = 1): F = 0.04 + 0.96·(1−1)⁵ = 0.04 — отражается 4%, видишь сквозь. На скользящем (cos θ → 0): F = 0.04 + 0.96·1⁵ = 1.0 — отражается 100%, чистое зеркало. Один параметр, ноль ручной подкрутки — и вода правильно ведёт себя и в луже под ногами, и у горизонта. Тот же закон рисует «рим» (светящийся контур) на любом объекте: на краю силуэта угол скользящий → Френель → подсветка кромки.
🕹 В какие игры поиграть — и что заметить
PBR коварен тем, что он невидим: это не эффект, а консистентность. Поэтому замечать надо тонкое: правильно ли читаются металл/пластик/кожа в одной сцене, и как на скользящем угле всё становится зеркальным. От витрины PBR к контрасту с до-PBR.
Ready at Dawn сделали игру-демонстрацию материалов: латунь, вороненая сталь, лак, ткань, кожа — каждый материал физически отдельный и верен под кинематографичным светом. Один из первых ААА-проектов «end-to-end PBR».
🎮 Сыграй: наведись на металлические детали оружия и на тканевые/кожаные — заметь, что блик у металла цветной и узкий, у кожи широкий и тусклый, и это не нарисовано, а одинаково работает при смене освещения по ходу сцены.
Идеальный стенд: машины из полированного и шершавого металла рядом с травой, кожей, тканью и кожей Элой. Один и тот же материал корпуса робота верно читается в полдень, в пыльной буре и ночью у костра — это и есть «масштабирование по свету» PBR.
🎮 Сыграй: поверни камеру так, чтобы солнце скользнуло вдоль мокрой/металлической поверхности — увидишь, как блик вспыхивает на скользящем угле (Френель), а в лоб поверхность тусклее. Сравни робота-металл и ткань: разная ширина блика = разный roughness.
DICE отсканировали реальные поверхности (фотограмметрия) и завели их как PBR-материалы — поэтому камень, металл и снег выглядят «как настоящие» под любым светом. Витрина того, как PBR + сканы дают фотореализм без ручного тюнинга.
🎮 Сыграй: найди контраст с до-PBR игрой (Half-Life 2, 2004): там блики «подрисованы» и под другим светом металл выглядит как крашеный пластик. Переключись на любую игру после ~2016 — разница в «честности» материала под движущимся светом бьёт в глаза.
Хардкор · теория: микрофасетный BRDF Кука–Торренса целикомможно пропустить
Зеркальная часть PBR — это микрофасетный BRDF Кука–Торренса: сколько света приходит с направления и уходит в . Три множителя, делённые на нормировку:
- D — распределение нормалей (NDF). Какая доля микрофасетов смотрит точно на полувектор (между и ) — то есть отражает свет ровно в глаз. Это и есть форма блика, и ей рулит roughness. Индустриальный стандарт — GGX / Trowbridge–Reitz (длинные «хвосты» — реалистичнее, чем у старого Blinn–Phong):
где (возведение в квадрат даёт перцептивно линейный ползунок). При функция вырождается в пик на — острый блик.
- F — Френель (Шлик, см. выше) — какая доля реально отражается под текущим углом; для металлов цветной .
- G — геометрия (затенение/маскирование). На скользящих углах микрофасеты загораживают друг друга — G гасит переотражение, иначе на гранях вылезает нефизичная пересветка. Зависит от roughness и углов (Smith-аппроксимация).
Диффузная часть — простой Ламберт , домноженная на (у металла диффуза нет) и на остаток энергии после зеркального бюджета. Итог: один и тот же код считает и зеркало, и пыль — меняются только α, F0 и metallic.
Хардкор · инженерия: текстурный workflow, каналы и где это считаетсяможно пропустить
На практике параметры — это текстуры, по одной на канал, и художник красит их в Substance Painter / на готовых сканах (Megascans):
- Base Color (albedo) — RGB, без теней и бликов (их добавит рендер).
- Roughness — один канал (grayscale): царапины, потёртости, мокрые пятна = локально разный roughness.
- Metallic — один канал, обычно почти бинарный (маска «где металл»).
- Normal map — мелкий рельеф без геометрии (см. «индекс вместо данных»: детали в текстуре, а не в полигонах).
- + AO, height, иногда переход на specular-glossiness workflow (альтернатива metallic-roughness).
Считается это в шейдере на каждый пиксель, обычно в deferred-конвейере: сначала геометрия пишет albedo/normal/roughness/metallic в G-буферы, потом свет считается по пикселям из них — стоимость растёт от числа источников света, а не от числа объектов. Именно это сочетание (PBR-материалы + deferred + HDR + тонмаппинг) и дало «современную картинку». Бизнес-следствие: материалы стали переносимыми библиотеками — Quixel Megascans, Adobe Substance, — и студия из трёх человек берёт ААА-материалы с полки, потому что PBR делает их композируемыми.
ML / AI (твой домен): BRDF — это аналитический, дифференцируемый prior, и это прямо мост в современный рендер-ML. Дифференцируемый рендеринг и NeRF / 3D Gaussian Splatting подставляют физическую модель отражения (часто тот же микрофасетный BRDF) внутрь обучения и оптимизируют материалы/свет градиентом — «inverse rendering». Это спор physics-based prior vs полностью выученная функция: вшитый BRDF = меньше данных, гарантированная обобщаемость на новый свет (ровно как PBR переносится между сценами), как у физически-информированных сетей (PINN). А «физически осмысленные оси вместо кучи ручек» = хороший дизайн признаков/латента: дизентанглмент (отдельно albedo / освещение / геометрия) обобщается, запутанные параметры — нет. Энергосбережение BRDF ⇄ нормировка/ограничения, удерживающие выход в валидном диапазоне.
Графика / симуляция: единая физическая модель материала переносится между растеризацией, трассировкой и path-tracing без переавторинга — один ассет, любой рендер.
Инженерия в целом: параметризуй систему по инвариантам (физические единицы, безразмерные числа), а не по удобным сейчас числам — тогда конфиг переносится между средами; «захардкодил под прод» = до-PBR материал, который ломается при смене условий.
Принцип: правильные оси важнее числа ручек. Параметризация, совпадающая с реальностью, делает перенос, композицию и обобщение бесплатными; подгонка под текущие условия — нет.
Лучший момент: поставь roughness в 0 и крути metallic 0→1 — увидишь, как диэлектрик (диффузный шар с белым бликом) превращается в полированный цветной металл без диффуза. Потом тяни roughness 0→1 — острый блик размазывается в матовую поверхность.
Если PBR «физически корректный», почему он всё ещё приближение (Шлик, GGX), а не настоящая оптика?
Почему metallic — почти бинарный? Разве не бывает «полуметаллов»?
Зачем roughness возводят в квадрат (α = roughness²)?
Почему до-PBR металл выглядел «крашеным пластиком» под другим светом?
PBR обещает «один материал под любым светом» — где он всё-таки врёт?
- Brent Burley, «Physically-Based Shading at Disney» (SIGGRAPH 2012) — первоисточник Principled BSDF, короткий и ясный.
- «Real-Time Rendering» (Akenine-Möller и др.), глава 9 — микрофасетные BRDF, Френель, GGX строго.
- «Physically Based Rendering» (Pharr, Jakob, Humphreys) — pbr-book.org, офлайн-референс целиком бесплатно.
- LearnOpenGL → раздел PBR (theory + lighting) — самый доступный код-туториал.
- Substance / ambientCG / Quixel Megascans — каналы материала и готовые библиотеки руками.
- Модуль 5, «PBR — the era's quiet revolution» (
05-hd-era-indie-revolution-2005-2012.md).