В Cannon.js контактный материал определяет
физические свойства взаимодействия между двумя объектами при их
столкновении. Основные параметры:
- friction — коэффициент трения, определяющий
сопротивление скольжению между объектами. Значения обычно находятся в
диапазоне 0–1.
- restitution — коэффициент упругости, задающий,
насколько объекты «отскакивают» друг от друга. Значение 0 соответствует
абсолютно неупругому столкновению, 1 — полностью упругому.
- stiffness — жесткость контакта, влияющая на силу, с
которой объекты сопротивляются проникновению друг в друга. Высокие
значения повышают точность, но могут вызвать нестабильность симуляции
при больших шагов интеграции.
- relaxation — демпфирование контакта. Позволяет
снижать колебания при столкновениях, улучшая стабильность.
Контактный материал создается через объект
CANNON.ContactMaterial и привязывается к паре
материалов с помощью world.addContactMaterial().
const groundMaterial = new CANNON.Material("ground");
const boxMaterial = new CANNON.Material("box");
const contactMaterial = new CANNON.ContactMaterial(
groundMaterial,
boxMaterial,
{
friction: 0.4,
restitution: 0.3,
stiffness: 1e7,
relaxation: 3
}
);
world.addContactMaterial(contactMaterial);
Влияние на стабильность
стека объектов
При построении стека объектов (например, колонны из
кубов) параметры контактного материала критически влияют на
устойчивость:
Трение (friction)
- Низкое трение (0–0.2) приводит к скольжению верхних объектов и
разрушению стека.
- Оптимальное значение трения для устойчивого стека обычно
0.3–0.6.
- Слишком высокое трение (>0.8) может вызвать «залипание» объектов
и неестественные колебания.
Упругость (restitution)
- Высокая упругость (>0.7) вызывает сильные отскоки при падении
объектов на нижние уровни, что может рассыпать стек.
- Для стабильного стека часто используется низкая упругость (0–0.2),
чтобы объекты аккуратно оседали друг на друга.
Жесткость контакта (stiffness)
- Низкая жесткость (<1e5) позволяет объектам «проваливаться» друг в
друга при столкновении, создавая визуальный артефакт и
нестабильность.
- Слишком высокая жесткость (>1e8) при больших временных шагах
интеграции может вызвать дрожание стека и численные расхождения.
- Баланс: подобрать stiffness так, чтобы объекты не проседали, но
симуляция оставалась стабильной.
Демпфирование (relaxation)
- Позволяет снижать колебания после контакта.
- Значения от 2 до 5 обеспечивают плавное погашение вибраций в
стеке.
- Слишком высокое демпфирование может «замораживать» объекты, делая
движение неестественным.
Применение комбинаций
материалов
Для сложных сцен часто используют несколько типов
материалов:
- Основание стека — более жесткий и менее упругий материал.
- Верхние объекты — немного более упругие и менее жесткие, чтобы сцена
выглядела динамичнее.
- При контакте разных типов материалов создается отдельный контактный
материал с индивидуальными параметрами трения и упругости.
const topBoxMaterial = new CANNON.Material("topBox");
const mixedContact = new CANNON.ContactMaterial(
groundMaterial,
topBoxMaterial,
{ friction: 0.5, restitution: 0.1, stiffness: 1e7, relaxation: 3 }
);
world.addContactMaterial(mixedContact);
Практические советы
для стабильного стека
- Малый шаг интеграции (timeStep ≤ 1/120) повышает
точность расчета контактов.
- Контактная жесткость должна быть сопоставима с
массой объектов: более тяжелые объекты требуют большей stiffness.
- Использовать небольшое демпфирование для устранения
мелких колебаний, особенно при высокой упругости.
- Избегать слишком высокой упругости для низких
объектов, чтобы предотвратить эффект «скачущей башни».
Эффективная комбинация этих параметров позволяет создавать
реалистичные и устойчивые стеки в Cannon.js, избегая проседания,
скольжения и численных нестабильностей.