如何在DirectX中规范模型大小

How to normalize model size in DirectX?

本文关键字:模型 范模型 DirectX      更新时间:2023-10-16

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

我记得在什么地方读到过它,但最近我看了很多DX的东西,我记不起它在哪里或是什么。我的问题是,假设我希望能够加载不同的模型,这些模型使用不同的单位,那么确保它们都具有相似的大小并适合屏幕的最佳方法是什么?

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

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

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

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
}

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