基于OpenXR XR_EXT_hand_tracking的手部独立骨骼渲染问题咨询
你的计算逻辑存在两处核心错误,同时还有几个容易被忽略的点会导致你遇到的抖动和拇指异常问题:
关于是否需要父骨骼变换
如果你确认XrHandJointLocationEXT返回的pose是世界空间全局位姿(也就是你调用xrLocateHandJoints时传入的baseSpace是跟踪空间原点),那么不需要额外叠加父骨骼的变换,因为返回的关节位姿已经包含了所有父节点的变换叠加结果。
如果你的baseSpace是手部根关节空间,返回的是相对父关节的局部位姿,才需要递归乘父骨骼的变换得到全局变换后再运算。
现有代码的问题排查
- 矩阵乘法顺序需核对
cglm为列主序矩阵,骨骼蒙皮的正确变换公式是:最终关节蒙皮矩阵 = 关节当前全局变换矩阵 × 逆绑定矩阵
你当前代码中的glm_mat4_mul(model->bones[i], model->inv_bind[i], model->bones[i])顺序是对的,但需要确认你加载的GLTF逆绑定矩阵是否是世界空间下的,如果是模型局部空间的逆绑定,需要先把手部整体的根变换乘入关节变换矩阵再和逆绑定相乘。 - 关节枚举映射错误是拇指异常的核心原因
OpenXR的XrHandJointEXT枚举顺序是固定的,从腕部到指尖依次排列,拇指的关节顺序为:掌骨→近端指骨→远端指骨→指尖。很多开发者会把Valve手部模型的骨骼索引和OpenXR枚举顺序弄混,尤其是拇指的掌骨和近端指骨索引搞反,直接导致拇指变形。你需要逐关节核对GLTF的骨骼索引和XrHandJointEXT枚举值的对应关系。 - 未做有效位过滤和滤波导致抖动
XrHandJointLocationEXT的locationFlags字段会标记当前关节的位置、方向是否有效,你现在的代码没有判断有效位,无效帧的脏数据会直接导致画面闪烁抖动。同时OpenXR的原始跟踪数据本身带噪声,你需要对每个关节的位置和四元数做低通平滑处理,比如用指数平滑或者四元数球面插值过滤噪声。 - 逆绑定矩阵校验
可以临时把所有逆绑定矩阵替换为单位矩阵测试,此时渲染的模型骨骼应该和你叠加的关节点位完全重合,如果不重合说明你加载GLTF时逆绑定矩阵读取错误。
内容的提问来源于stack exchange,提问作者bl4ckb0ne
相关产品推荐
相关产品推荐

