使用几何体混合 (Direct3D 9)
以下用户定义的结构可用于将在两个矩阵之间混合的顶点。
// The flexible vertex format (FVF) descriptor for this vertex would be:
// FVF = D3DFVF_XYZB1 | D3DFVF_NORMAL | D3DFVF_TEX1;
struct D3DBLENDVERTEX {
D3DVECTOR v;
FLOAT blend;
D3DVECTOR n;
FLOAT tu, tv;
};
混合权重必须出现在 FVF 中的位置和 RHW 数据之后,并且出现在顶点法线之前。
请注意,前面的顶点格式仅包含一个混合权重值。 这是因为将有两个世界矩阵,在 D3DTS_WORLDMATRIX (0) 和 D3DTS_WORLDMATRIX (1) 转换状态中定义。 系统使用单个权重值在这两个矩阵之间混合每个顶点。 对于三个矩阵,只需要两个权重,依类而行。
注意
定义皮肤重量非常简单。 使用关节之间距离的线性函数是良好的开端,但更平滑的 sigmoid 函数看起来更好。 如果需要,选择皮肤重量分布函数可能会导致关节出现尖锐的折痕,方法是在短距离内使用皮肤重量的较大变化。
设置混合矩阵
通过调用 IDirect3DDevice9::SetTransform 方法设置系统混合的转换矩阵。 将第一个参数设置为 D3DTS_WORLDMATRIX 宏定义的值,并将第二个参数设置为要设置的矩阵的地址。
以下 C++ 代码示例设置两个世界矩阵,两个世界矩阵之间混合几何图形以创建关节臂的错觉。
// For this example, the d3dDevice variable is assumed to be a valid pointer
// to an IDirect3DDevice9 interface for an initialized 3D scene.
float BendAngle = 3.1415926f / 4.0f; // 45 degrees
D3DMATRIX matUpperArm, matLowerArm;
// The upper arm is immobile. Use the identity matrix.
D3DXMatrixIdentity( matUpperArm );
d3dDevice->SetTransform( D3DTS_WORLDMATRIX(0), &matUpperArm );
// The lower arm rotates about the x-axis, attached to the upper arm.
D3DXMatrixRotationX( matLowerArm, -BendAngle );
d3dDevice->SetTransform( D3DTS_WORLDMATRIX(1), &matLowerArm );
设置混合矩阵只会使系统缓存矩阵供以后使用;它不会指示系统开始混合顶点。
启用几何混合
默认情况下,几何混合处于禁用状态。 若要启用几何图形混合,请调用 IDirect3DDevice9::SetRenderState 方法,将D3DRS_VERTEXBLEND呈现状态设置为 D3DVERTEXBLENDFLAGS 枚举类型中的值。 下面的代码示例演示在为两个世界矩阵之间的混合设置呈现状态时,此调用可能是什么样子。
d3dDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS );
当D3DRS_VERTEXBLEND设置为除 D3DVBF_DISABLE 以外的任何值时,系统假定顶点格式中将包含适当数量的混合权重。 你负责提供合规的顶点格式,并为 Direct3D 呈现方法提供该格式的正确说明。
启用后,系统将对 DrawPrimitive 呈现方法呈现的所有对象执行几何图形混合。
另请参阅
相关主题