Стекло, кристаллы и капли: материалы, которые ломают шейдер
Я потратил неделю, пытаясь сделать честный кристалл, прежде чем старший артист посмотрел мой шейдер и сказал: «Ты знаешь, что игрок будет смотреть на это два секунды?» Не знал. А потом понял, что стекло, кристаллы и капли — это не материал, а три физически разных задачи, и шейдер они ломают по-разному.
Почему стекло — это боль
Обычный объект рисуется так: посмотрел на себя, покрасился. Стекло обязано посмотреть сквозь себя на то, что сзади, — а это сцена, которая ещё не нарисована. Получается курица и яйцо: чтобы отрендерить прозрачное, нужен готовый непрозрачный буфер. Отсюда закон: прозрачность рендерится последней, сортируется по дальности и никогда не попадает в depth buffer нормально. Два слоя стекла рядом — и начинается ад с наложением.
Преломление: луч сворачивает
Свет в стекле идёт медленнее, поэтому на входе луч отклоняется — показатель преломления IOR у стекла ~1.5, у воды 1.33, у алмаза 2.42. Дешёвая реализация для игр: вместо настоящего трекинга луча берём вектор рефракции и выбираем им из скрин-текстуры сдвинутые пиксели. Кривизна нормали делает искажение — и мозг верит. Это «стекло за пять строк», и оно спасает 90% случаев.
Дисперсия: когда стекло врёт цветами
Разные длины волн преломляются по-разному — белый луч распадается на радугу. У настоящего кристалла это главный фокус. Полный вариант — три выборки с разным IOR для R, G, B — дорог. Дешёвый трюк: одна выборка, но смещённая по нормали, плюс цветная кайма по силуэту из Fresnel. Выглядит на 80% как настоящая дисперсия, стоит 5% бюджета.
Total internal reflection: ловушка для света
Под крутым углом луч не выходит наружу, а отражается внутри — поэтому кристалл изнутри ярче, чем снаружи, и светится гранями. В шейдере это бесплатно: Fresnel-множитель на отражение уже почти TIR. Настоящая симуляция требует реймаршинга или кубических карт, снятых изнутри объекта — приём из кино, в играх редкий.
Дешёвые трюки, которые работают
- Капли: не симуляция, а normal-карта с нарисованными каплями + растянутый по силе тяжести блик. Капля на лбу персонажа в кино — это карта, а не жидкость.
- Кристалл-самоцвет: матовое стекло (high roughness) + внутренняя эмиссия по маске трещин. Светится «изнутри» за один проход, без прозрачности вообще.
- Мокрая поверхность: не прозрачность, а слой: тёмный diffuse + резкий specular + Fresnel-затемнение. Дождь на стекле — это капли-оверлей на окне камеры, а не 3D.
- Стакан с жидкостью: два цилиндра, у жидкости верхняя плоскость чуть вогнута — глаз ищет именно мениск, остальное простит.
Что выбрать
Правило дистанции: герой-предмет крупным планом — честная рефракция с дисперсией; фон и добыча — скрин-текстура; массовое (дождь, пузырьки) — карты и оверлеи. Стекло ломает шейдер не потому, что сложное, а потому что честное его решение стоит как десять обычных материалов. Игрок этого не оценит — он смотрит два секунды.
Комментарии (1)
Дисперсия через три сэмпла с разным IOR — простой трюк, а выглядит дорого. Взял.
Форма для гостей комментариев пока не принимается — писать можно автору (expeot@outlook.com) или через владельца блога. Все записи выше настоящие, никто их не модерирует молча.