directx
程序多开器-三星移动硬盘打不开
2023年4月4日发(作者:dnf超级助手)DirectX数学介绍
本⽂为Introductionto3DGameProgrammingwithDirectX11读书笔记
坐标系统
DirectX使⽤的是左⼿坐标系,使⽤左⼿坐标系计算叉乘的时候⽅向⽤左⼿决定
书上给的图如下
VectorAlgebra
win10已经把DirectX11集成到了windowsSDK中,所以如果是使⽤win10做开发,则不需要⼿动下载DirectX11的类库。
对于D3D11,数学计算库⽤XNAMathlibrary,该库提供了SIMD指令的封装,SIMD是单指令多数据,简⽽⾔之就是计算速度更快,所
以在每当要做计算的时候就要对矩阵、向量等做类型转换。
要使⽤XNAMathlibrary只要,原先是xnmath.h,但是早就不可⽤了,下⾯是正确的
SIMD⼀条指令使⽤多个数据,⽐如4个32位的数都放到⼀个128位的寄存器上,然后执⾏⼀次运算指令,得到输出,这样对于同样的操
作,执⾏4次指令,得到输出要快⼤约4倍。
XNAMath定义的可以执⾏SIMD的Vector类型是XMVECTOR,这是⼀个128位的类型,可以⽤SIMD指令处理4个32位的浮点数。如果
机器⽀持SSE2,则将会有定义
XMVECTOR需要16位对齐,对于局部变量和全局变量都是如此,上⾯解释了SIMD,需要把整块数据都移到寄存器上,但这都是⾃动完成
的。
对于⼀般的类中使⽤的变脸则使⽤⼀般的struct类型就⾏了,只有在需要计算的时候才做转换。
⼀般的类型基本如下,之后说到的矩阵也是类似的情况。
XMFLOAT*类型与XMVECTOR类型的相互转换。
#include
#include
usingnamespaceDirectX;
usingnamespaceDirectX::PackedVector;
typedef__m128XMVECTOR;
typedefstruct_XMFLOAT2{
FLOATx;
FLOATy;
}XMFLOAT2;
typedefstruct_XMFLOAT3{
FLOATx;
FLOATy;
FLOATz;
}XMFLOAT3;
typedefstruct_XMFLOAT4{
FLOATx;
FLOATy;
FLOATz;
FLOATw;
}XMFLOAT4;
有很多⽅法都已经被DirectXMath⾼效的实现了,要善⽤⾼效的⽅法。
MatrixAlgebra
矩阵的情况跟向量的⼀样,简单说⼀下常⽤的矩阵的性质:
⾏列式
矩阵的⾏列式在计算逆矩阵的时候会⽤到,,更多的看wiki,⾏列式返回⼀个实数
//LoadsXMFLOAT2intoXMVECTOR
XMVECTORXMLoadFloat2(CONSTXMFLOAT2*pSource);
//LoadsXMFLOAT3intoXMVECTOR
XMVECTORXMLoadFloat3(CONSTXMFLOAT3*pSource);
//LoadsXMFLOAT4intoXMVECTOR
XMVECTORXMLoadFloat4(CONSTXMFLOAT4*pSource);
//Loads3-elementUINTarrayintoXMVECTOR
XMVECTORXMLoadInt3(CONSTUINT*pSource);
//LoadsXMCOLORintoXMVECTOR
XMVECTORXMLoadColor(CONSTXMCOLOR*pSource);
//LoadsXMBYTE4intoXMVECTOR
XMVECTORXMLoadByte4(CONSTXMBYTE4*pSource);
//LoadsXMVECTORintoXMFLOAT2
VOIDXMStoreFloat2(XMFLOAT2*pDestination,FXMVECTORV);
//LoadsXMVECTORintoXMFLOAT3
VOIDXMStoreFloat3(XMFLOAT3*pDestination,FXMVECTORV);
//LoadsXMVECTORintoXMFLOAT4
VOIDXMStoreFloat4(XMFLOAT4*pDestination,FXMVECTORV);
//LoadsXMVECTORinto3elementUINTarray
VOIDXMStoreInt3(UINT*pDestination,FXMVECTORV);
//LoadsXMVECTORintoXMCOLOR
VOIDXMStoreColor(XMCOLOR*pDestination,FXMVECTORV);
//LoadsXMVECTORintoXMBYTE4
VOIDXMStoreByte4(XMBYTE4*pDestination,FXMVECTORV);
FLOATXMVectorGetX(FXMVECTORV);
FLOATXMVectorGetY(FXMVECTORV);
FLOATXMVectorGetZ(FXMVECTORV);
FLOATXMVectorGetW(FXMVECTORV);
XMVECTORXMVectorSetX(FXMVECTORV,FLOATx);
XMVECTORXMVectorSetY(FXMVECTORV,FLOATy);
XMVECTORXMVectorSetZ(FXMVECTORV,FLOATz);
XMVECTORXMVectorSetW(FXMVECTORV,FLOATw);
类型定义
//32-bitWindows
typedefconstXMVECTORFXMVECTOR;
typedefconstXMVECTOR&CXMVECTOR;
//64-bitWindows
typedefconstXMVECTOR&FXMVECTOR;
typedefconstXMVECTOR&CXMVECTOR;
伴随矩阵
设矩阵,将矩阵A的元素所在的第i⾏第j列元素划去后,剩余的个元素按原来的排列顺序组成的n-1阶矩阵所确定的⾏列式称为元素的余⼦
式,记为,称为元素的代数余⼦式。
⽅阵的各元素的代数余⼦式所构成的如下矩阵:
该矩阵称为矩阵A的伴随矩阵。
逆矩阵
当然最基础还是矩阵与逆矩阵的乘机为单位矩阵
XNA类型跟Vector⾮常类似
TRANSFORMATIONS
下⾯说到的矩阵变换表⽰都是对向量右乘⼀个矩阵,对向量执⾏矩阵的变换
缩放
矩阵表⽰,沿着轴旋转的缩放系数分别是
其逆矩阵为
例⼦
旋转
绕任意轴旋转,⽐如绕轴旋转,假设为单位长度。此时向量v要绕着轴n旋转⾓度,得到。把v分解为平⾏于n的部分和垂直于n的部分.
由上图可以得到
把上⾯公式写成跟公式(1)类似的,对向量做旋转,矩阵形式如下,其中:
⽽且该矩阵为正交矩阵,正交矩阵的逆为其转置
则作为特殊情况,绕轴分别旋转的旋转矩阵分别如下
仿射变换
仿射变换就是带偏移的线性变换,可以表⽰为如下:
但是上⾯的写法很⿇烦,所以⽤4维向量和矩阵计算将会更简洁⾼效,因为GPU本⾝就是并⾏运算能⼒超强。
所以上⾯改写为如下:
上⾯是对点的变换,所以把最后⼀项设置为1,因为点有偏移;但是,对于向量来说,是没有偏移这个概念的,所以最后⼀项设置为0。这
样的4维向量和矩阵才是图形学中常⽤的形式。
移动
转移矩阵可以写为
其逆矩阵
对缩放和旋转的仿射矩阵
仿射变换矩阵的⼏何解释
上⾯介绍的仿射变换就是旋转/缩放,移动
⽤公式表⽰如下(其中对于顶点,对于向量):
因为矩阵有结合律但没有交换律,所以矩阵相乘最后作⽤于对象的顺序⾮常关键,是先旋转再平移与先平移再旋转有很⼤差别。
坐标系变换
摄⽒度与华⽒度表⽰相同的问题时数字⼤⼩是不⼀样的,不同的基底(坐标系)之间的转换得到相同坐标不同的表⽰。
对基底的变换与做顶点和向量的变换不同,刚好是完全相反的。
简单的坐标系统变换
顶点和向量的坐标转换,将坐标系A下的顶点表⽰转换为坐标系B下的顶点表⽰。
跟之前介绍的⼀样,表⽰对向量的坐标系变换,表⽰对顶点的变换。
上式写成矩阵形式
其中分别表⽰原点以及齐次坐标系A相对于齐次坐标系B的轴。
给个例⼦,如下图:
⽐较转换矩阵和坐标系变换矩阵
TRANSFORMATIONMATRIXVERSUSCHANGEOFCOORDINATEMATRIX
其实两者数学上是等价的,不同之处在于理解和解释转换的⽅式有所不同
XNA的实现
在XNA中,所有这些转换都已经实现了
//Constructsascalingmatrix:
XMMATRIXXMMatrixScaling(
FLOATScaleX,
FLOATScaleY,
FLOATScaleZ);//Scalingfactors
//Constructsascalingmatrixfromcomponentsinvector:
XMMATRIXXMMatrixScalingFromVector(
FXMVECTORScale);//Scalingfactors(sx,sy,sz)
//Constructsax-axisrotationmatrix:Rx
XMMATRIXXMMatrixRotationX(
FLOATAngle);//Clockwiseangleθtorotate
//Constructsay-axisrotationmatrix:Ry
XMMATRIXXMMatrixRotationY(
FLOATAngle);//Clockwiseangleθtorotate
//Constructsaz-axisrotationmatrix:Rz
XMMATRIXXMMatrixRotationZ(
FLOATAngle);//Clockwiseangleθtorotate
//Constructsanarbitraryaxisrotationmatrix:Rn
XMMATRIXXMMatrixRotationAxis(
FXMVECTORAxis,//Axisntorotateabout
FLOATAngle);//Clockwiseangleθtorotate
//Constructsatranslationmatrix:
XMMATRIXXMMatrixTranslation(
FLOATOffsetX,
FLOATOffsetY,
FLOATOffsetZ);//Translationfactors
//Constructsatranslationmatrixfromcomponentsinavector:
XMMATRIXXMMatrixTranslationFromVector(
FXMVECTOROffset);//Translationfactors(tx,ty,tz)
//Computesthevector-matrixproductvM:
XMVECTORXMVector3Transform(
FXMVECTORV,//Inputv
CXMMATRIXM);//InputM
//Computesthevector-matrixproductvMwherevw=1fortransformingpoints:
XMVECTORXMVector3TransformCoord(
FXMVECTORV,//Inputv
CXMMATRIXM);//InputM
//Computesthevector-matrixproductvMwherevw=0fortransformingvectors:
XMVECTORXMVector3TransformNormal(
FXMVECTORV,//Inputv
CXMMATRIXM);//InputM
directx