1

我在 DirectX 中创建了一个简单的“引擎”,它可以从 .obj 文件加载和渲染模型。对于我创建的对象,它可以正常工作,例如,坐标在 -1.0 到 1.0 范围内的简单立方体。然而,加载一个使用不同单位并且坐标在 -2k 到 2k 范围内的模型会导致一个巨大的东西,它甚至不完全适合深度缓冲区,所以我看到一个巨大的腿或类似的效果。

我记得在某处读过它,但最近我经历了很多 DX 的东西,我不记得它在哪里或是什么。所以我的问题是,假设我希望能够加载使用不同单位的不同模型,那么确保它们都具有相似尺寸并很好地适合屏幕的最佳方法是什么?

我可以尝试在加载对象时转换值,但也许还有更多使用转换矩阵或着色器的 DirectX 方式?

4

1 回答 1

2

最简单的方法是找出模型在哪个组件上包含最大范围,并使用该值统一缩放模型。要找到最大范围,请计算模型边界框(除非波前 obj. 文件已经提供它,但也许您还是想验证它),并使用框尺寸作为比较范围。这会将所有导入的模型缩小到单位范围。

例如,如果您有一个模型的边界框覆盖 374 * 820 * 512 个单位,那么最大的一个是 820 的 Y 轴,因此您只需将其缩小 820(将所有组件除以 820)。这可以通过统一缩放矩阵方便地实现D3DXMatrixScaling,如果我没记错的话,可以使用 初始化。假设边界框由 2 个向量(最大和最小顶点)给出,计算这些向量的差,然后选择最大值,并将其逆作为矩阵的缩放因子。

D3DMatrix mScale;
D3DVector mx, mn;
obj->getBoundingBox(&mn,&mx);
float scale = 1.0 / max(mx.x - mn.x, max(mx.y - mn.y, mx.z -mn.z));
D3DXMatrixScaling( &mScale, scale, scale,scale);

剩下要做的就是在渲染管道中插入矩阵。

关于边界框的计算,应该在模型的所有顶点上进行一个简单的循环,保持最小和最大分量(彼此独立)。

D3DVector mn, mx;
mn.x = mn.y = mn.z = MAX_FLOAT;
mx.x = mx.y = mx.z = - MAX_FLOAT;
for (int i = 0; i < numVertices ; i++) {
   mn.x = min(mn.x, vertex[i].x);
   mn.y = min(mn.y, vertex[i].y);
   mn.z = min(mn.z, vertex[i].z);
  // same for mx using max
}

当然,如果您的视图覆盖的区域比单位框大(但显然这是您正在使用的),您可能需要使用一些缩放因子。

于 2012-12-29T03:19:56.890 回答