c++ - 如何在 DirectX 中标准化模型大小?

标签 c++ 3d directx normalization wavefront

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

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

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

最佳答案

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

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

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
}

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

关于c++ - 如何在 DirectX 中标准化模型大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14078093/

相关文章:

c++ - 内部数组访问比 std::vector 访问快得多——Black Magic?

java - 将表面拟合到 java 中的 3D 数据点集合

opengl - 为什么索引缓冲区对象没有 glVertexAttribPointer?

c++ - 代码按下的按钮

c++ - 锁定和操作需要很长时间

C++ - 使用 live555 库的带有 Qt GUI 的 RTSP 客户端我还需要什么?

c++ - 根据用户输入对文件进行排序

r - 如何将等值面夹到球上?

opengl - 现代图形管道有多少帧深?

c++ - 正确使用 d3d9 的后台缓冲功能