Лай эту проблему в OpenGL лает неправильное дерево: единственная цель OpenGL - рисовать красивые картинки на экране. Это не математическая библиотека!
В зависимости от ваших требований существует несколько решений. Вот как я бы решил эту проблему: нормали, которые вы вычисляете для правильного затенения, дают наклон каждой точки. Скажем, ваша карта высот (= ландшафт) находится в плоскости XY, а ваш гравитационный вектор g = -Z
, тогда нормальная сила равна terrain_normal(x,y) · g
. Нормальная сила - это то, что «толкает» ваши ноги о землю. Без достаточной нормальной силы недостаточно трения, чтобы передать силу мышц в движение, перпендикулярное земле. Если вы посмотрите на формулу нормальной силы, то увидите, что чем больше угол между g
и terrain_normal(x,y)
отклоняется, тем меньше нормальная сила.
Таким образом, в вашей программе вы можете просто проверить, превышает ли нормальная сила какой-либо порог; правильно вы проецируете приведенную силу трения на местность и используете ее в качестве вектора ускорения.