Я вращаю кости скелета внутри сетки для низкой поли 3D-фигуры. На вершинном шейдере это применяется так.
GLSL:
vec4 vert1 = (bone_matrix[index1]*vertex_in)*weight;
vec4 vert2 = (bone_matrix[index2]*vertex_in)*(1-weight);
gl_Position = vert1+vert2;
bone_matrix[index1]
- матрица одной кости, а bone_matrix[index2]
- матрица другого. weight
обозначает vertex_in
членство в этих костях. Проблема заключается в том, что чем ближе вес к .5, тем больше диаметр локтя сжимается при приложении вращения. Я протестировал его около 10 000 вершинного цилиндра (с градиентом весов). Результат был похож на изгиб садового шланга.
Я получил свой метод взвешивания из этих источников. Фактически это единственный способ найти:
http://www.opengl.org/wiki/Skeletal_Animation
http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html
http://blenderecia.orgfree.com/blender/skinning_proposal.pdf
Левый - это то, как начинается форма, а середина - это то, как приведенное выше уравнение вращает ее, а правая - моя цель. Средние точки взвешены 0.5
. Это только ухудшается, тем больше он изогнут, на 180 градусов он имеет нулевой диаметр.
- Я попытался собрать матрицу на шейдере, чтобы я мог применять весы к вращению вместо результирующих вершин. Он выглядит идеально, как тот, что изображен справа, но требует сборки матрицы для каждой вершины (дорогой).
- Я изучил кватернионы, но glsl не поддерживает их (исправьте меня, если я ошибаюсь), и они запутывают. Это то, что мне нужно сделать?
- Я рассмотрел наличие трех костей на сустав и добавил "колено" между каждой костью. Это не устранит проблему, а уменьшит ее.
- Я рассматриваю проецирование вершины на свое первоначальное расстояние от оси после поворота. Это провалится на 180 градусов, но будет (относительно) дешевым.
Итак, рассматривая варианты или другие варианты, которые я, возможно, не рассматривал, Как другие избегают этого эффекта сжатия?
EDIT: Я получил SLERP для работы с использованием кватернионов, но я решил не использовать его, поскольку GLSL не поддерживает его. Я не мог заставить геометрический SLERP работать, как описано Томом. Я получил NLERP, работающий на первые 90 градусов, поэтому я добавил дополнительную "кость" между каждым суставом. Поэтому, чтобы сгибать предплечье 40 градусов, я сгибаю локоть и предплечье на 20 градусов каждый. Это устраняет эффект защемления за счет удвоения количества костей, которое не является идеальным решением.