d3d中左手系到右手系转换需要注意事项

时间:2023-01-08 13:11:12

在d3d中默认使用左手系坐标,其实就是在生成变换矩阵时,习惯使用带有LH后缀的函数,如LookAtLH、PerspectiveFovLH等。但是大部分编辑器(如Maya)使用的是右手系坐标,所以会在导入相关模型的时候转换到左手系。但这样会导致应用程序空间和编辑器控件不一致,写程序时非常麻烦。

d3d中左手系到右手系转换需要注意事项

我这边决定直接使用右手系坐标,终结下需要注意的事项:

模型空间

如果使用的模型是左手系空间的,则需要对定点、法线等数据的 z 值取反,但是Maya默认使用右手系,则在导入时可以将数据原封不动的装入

Culling Mode

理论上,右手系空间应当使用逆时针顺序(CCW,counterclockwise)作为三角形的正面,但是这也可以取决于编辑器,如Maya使用顺时针,那也以可直设置成CW模式

View空间

View空间右可理解为相机空间,这里要注意的是左手系的View空间是 Z 轴向外,而右手系则是 Z 轴向内(即正 Z 轴方向与相机相反),所以在生成 uvn 矩阵的时候要注意

n=normalize(eye - at),参见 D3DXMatrixLookAtRH

Vector3 zaxis = (eye - at).normalize();
Vector3 xaxis = up.cross(zaxis).normalize();
Vector3 yaxis = zaxis.cross(xaxis);

return Matrix4(
	xaxis.x,			yaxis.x,			zaxis.x,			0,
	xaxis.y,			yaxis.y,			zaxis.y,			0,
	xaxis.z,			yaxis.z,			zaxis.z,			0,
	-xaxis.dot(eye),	-yaxis.dot(eye),	-zaxis.dot(eye),	1);

Projection空间

既然右手系中 Z 轴与相机正方向相反,那么这里的 Near Z、Far Z 的理解就不同了,由于通常 Near Z、Far Z 描述成正值,那么在求解透视矩阵时,就要对其反向处理(这一点和左手系是不同的),参见 D3DXMatrixPerspectiveFovRH

float yScale = cot(fovy / 2);
float xScale = yScale / aspect;

return Matrix4(
	xScale,	0,		0,						0,
	0,		yScale,	0,						0,
	0,		0,		zf / (zn - zf),			-1,
	0,		0,		zn * zf / (zn - zf),	0);