XR_EXT_hand_tracking拡張XrHandJointLocationEXT
からの配列によって指定された位置に基づいて、3D 空間で手のモデルをレンダリングしようとしています。XrHandJointEXT列挙型の OpenXR 仕様で定義されたジョイントに一致する正しい量のボーンを持つ Valve の両方のGTLF ハンド モデルを使用しています。
私は次のようにレンダリングを行います:
フレームごとに、現在の変換に GLTF モデルから取得した逆バインド マトリックスを乗算することで、各ジョイントを個別に更新します。はXrPosef
、3D 空間の中心に相対的です。すべての行列計算を処理するためにcglmを使用しています。
for (size_t i = 0; i < XR_HAND_JOINT_COUNT_EXT; ++i) {
const XrHandJointLocationEXT *joint = &locations->jointLocations[i];
const XrPosef *pose = &joint->pose;
glm_mat4_identity(model->bones[i]);
vec3 position;
wxrc_xr_vector3f_to_cglm(&pose->position, position);
glm_translate(model->bones[i], position);
versor orientation;
wxrc_xr_quaternion_to_cglm(&pose->orientation, orientation);
glm_quat_rotate(model->bones[i], orientation, model->bones[i]);
glm_mat4_mul(model->bones[i], model->inv_bind[i], model->bones[i]);
}
次に、HMD
ごとに計算されbones
た行列と共に、配列が頂点シェーダーにアップロードされます。view-proj
eye
#version 320 es"
uniform mat4 vp;
uniform mat4 bones[26];
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 tex_coord;
layout (location = 2) in uvec4 joint;
layout (location = 3) in vec4 weight;
out vec2 vert_tex_coord;
void main() {
mat4 skin =
bones[joint.x] * weight.x +
bones[joint.y] * weight.y +
bones[joint.z] * weight.z +
bones[joint.w] * weight.w;
gl_Position = vp * skin * vec4(pos, 1.0);
vert_tex_coord = tex_coord;
}
計算方法は正しいですか?まともな結果が得られますが、「グリッチ」があります。次のスクリーンショットでわかるように、手のモデルの上に両方の独立したジョイントをレンダリングしました。親指に不具合が見られます。
ボーン トランスフォームを計算するとき、親ボーンを考慮する必要がありますか?