图形学数学变换的领悟-持续更新

一、基本概念和前提

基本矩阵含义,四元数含义,欧拉角。 理解矩阵的 基向量特点 分解组合作用;四元数有一般的信息在变换乘法中;欧拉角存在万向锁
不同坐标系下乘法顺序,矩阵逆,旋转绕向,正面定义不同。
变换坐标系区别(左手坐标系,右手坐标系是不同的,3ds max坐标系),矩阵行列式的区别,乘法顺序的区别,正反面的区别,一定要清楚变换前提条件,否则很容易导致难以觉察的计算错误。

二、变换物体和变换坐标系的联系区别

变换坐标系来实现变换例如的视图变换,变换物体达到的方位,可以通过相反的方向变换坐标系做到(但是变换坐标系其实是用逆变换变换物体实现)。世界坐标系是一个目标空间中,预先定义的原点一般是屏幕中心位置,在世界模型空间中,其它模型坐标系包括摄像机坐标系都是通过上述屏幕中心位置为参考点定义的,世界坐标系一般不用定义, 因为是从屏幕中心不做任何变换下(用2D摄像机且没有偏移)逆向变换过来的位置,光照计算一般都转换到世界坐标系中计算和光源与顶点间的相对位置(摄像机坐标系中计算 光源和顶点的位置也是可以的)。

DX屏幕坐标系是左上角是(0,0)右下角为(1,1); OGL屏幕坐标系左下角为(0,0),右上角为(1,1);都是正向的将图形绘制到屏幕正确位置,只是物体的屏幕坐标系位置标识有区分,片段着色器取样后,显示器直接从上往下绘制后台缓冲即可。但是DX和OGL的纹理坐标都是相对于屏幕坐标系的,在DX和OGL上工作根据不同的屏幕指定不同的纹理坐标即可,如果在两个图形库之间切换,三角网格顶点和索引顺序不变,纹理坐标需要(1-u,1-v)作为顶点的uv。

贴图格式存储一般第一行是左下角的。显示器屏幕坐标系一般是左上角为(0,0)的,Click point位置会取到,逆向变换返回即可,所以UGUI模型坐标系是左下角的,但是鼠标点击的响应屏幕坐标系是左上角的,正确处理即可,没有什么可讨论的

三、单一的完整变换的顺序和转换为线性变换(过原点)

单一坐标系中的完整缩放旋转平移,OGL是平移旋转缩放。其中原因DX一说是变换基于的坐标都是原坐标系的变换,缩放不影响基于原坐标系的旋转平移,旋转不影响基于原坐标系的平移,最后平移,顺序乱了会有问题;OGL中说是变换基于的坐标系都是基于本地Local坐标系的,平移不影响基于Local的旋转缩放,旋转不影响基于Local的缩放,最后缩放,顺序乱了会有问题。其实都可以解释得通,但是最主要的原因是按照乘法规则和乘法顺序,DX下只有SRT,OGL下书面写是M^t= (SRT)^t=T^t*R^t*S^t,但是是从右往左乘所以X写法是S^t*R^t* T^t, ^t是转置,代码中的顺序是glTranslate->glRotate->glScale的顺序。
非线性变换,也就是不在原点的变换,可以先想物体变换回原点,然后进行线性变换,经过线性变换后再变换到原来的状态。变换的过程中一定要清楚变换的顺序,否则会导致问题。

四、嵌套坐标系在左手,右手父子上行(物惯)下行(惯物)的连续变换

U3D中的transform是对它上面的物体或子物体产生影响的,所以要计算它自己的position在父节点的父节点中的位置(世界坐标系是左手坐标系)是:
Vparent-parent = Vpos * Sparent * Rparent + Tparent
这是物惯变换,在父子坐标系中的惯物变换是,例如知道上面的子节点的世界坐标系,那么求子节点中的local坐标系;
那么: Vpos = (Vparent-parent - Tparent) * (Sparent * Rparent)^-1  = (Vparent-parent - Tparent) * Rparent^-1 * Sparent *^-1 顺序相反量相反(取逆变换)实现。
骨骼动画,复杂的特效表现,类似这样的处理。

五、各种变换之间的灵活转换思想

1.不同坐标系,左手,右手坐标系,3ds max坐标系,不同的坐标系统之间的转换。
2.各种变换之间的转换,例如四元数,欧拉角,矩阵间的转换。
3.为了得到目标空间位置,在各个摄像机,各个坐标空间,坐标位置之间的变换,和相对变换。
见:http://blog.csdn.net/blues1021/article/details/46289403
更多具体后面补充。

六、图形渲染中的变换和应用

模型坐标系 (OGL右手,DX左手)->世界坐标系(OGL右手,DX左手)->视图(摄像机)坐标系( OGL右手,DX左手,变换了坐标系而不是物体,在视图坐标系中可能进行光照计算)->投影(裁剪坐标系或正交直接到NDC坐标系)坐标系(OGL 右手,DX左手)->硬件进行裁剪和透视除法(2D正交投影没有除法)->NDC规范化坐标系(OGL,DX都是变为了左手坐标系)->屏幕坐标系背面剔除(OGL左下角,DX右上角,有些UI世界坐标系可能不同3D世界坐标系)->接着进行片元插值会丢弃了冗余的片元屏幕坐标位置->Fragment Shader->全局雾计算 alpha stencil depth测试(遮挡剔除)->源帧缓存到目标后台缓存(之前的draw call)进行融合 抖动逻辑操作->写入目标后台缓存->flush/swapbuffer提交后台缓存到屏幕监视器显示2D图像
D3D图形API是从前往后的顺序来进行矩阵乘法设置,OGL是从后往前的顺序来进行矩阵乘法设置,原因是:
Mtotal = Vector * Mworld * Mview * Mproject or ortho(3d中要硬件/w到ndc) * Mviewport
Mtotal的转置为单个矩阵转置相反的顺序相乘,虽然写法是从右往左乘,但代码中还是列式矩阵,相反顺序相乘的。

透视投影的图形学式的透视和部分投影到4D中的思想,统一左手的 NDC坐标系,映射到不同的屏幕坐标系。


网格中顶点位置法向量光照的计算, 法向量转换到视图空间的计算和顶点转换到视图空间的计算不一样?应该是一样的具体有机会研究下。


用gluPerspective函数构造的是一个对称的视锥,如果你想要构造非对称视锥必须直接使用glFrustum()函数。例如,你想要把一个宽场景绘制到两个相连的屏幕上,你可以将视锥分割为左右两个非对称的视锥,然后在每个视锥中渲染场景。
GL_TEXTURE纹理矩阵
纹理坐标(s,t,r,q)在进行任何纹理映射前乘以GL_TEXTURE。默认情况下,它是一个单位阵,因此纹理会被映射到物体的位置,那个你指定纹理坐标的位置。通过修改GL_TEXTURE,你可以滑动、旋转、拉伸以及收缩纹理。
glMatrixMode(GL_TEXTURE);
glRotatef(angle, 1, 0, 0)


GL_COLOR 颜色矩阵
颜色分量(r,g,b,a)乘以GL_COLOR矩阵。可以用于颜色空间转换和颜色分量交换。GL_COLOR矩阵被经常使用,并且需要GL_ARB_imaging拓展。

七、实践工程中的变换通过建模数学思维灵活处理变换

最好不要复杂的变量,通过中间变量,相对位置来计算。通过转换数学思想来实现。
转换时候进行的各种辅助变换,不满足要求的变换,转换到标准位置,例如费放射变换平移回原点;通过相对位置变换,骨骼动画中运动是相对网格位置的;通过中间位置来变换例如屏幕坐标系,不同摄像机之间的变换。
变换的不断实践和积累和研究,例如ogre中的逆向动力学,复杂的骨骼动画,粒子特性。
-- 例如地图的边界通过摄像机和屏幕坐标系变换到世界中得到,
-- 士兵的位置在mainCamera中转换屏幕坐标系再转到UICamera中mUICamera.ScreenToWorldPoint(uiScreenPos)中。
-- UI坐标中转换到屏幕坐标,包含z值;转换到MainCamera world space中,每帧刷新mainCamera 的Pos在摄像机中的位置再布局位置即可。
--  嵌套坐标系中的变换, 子坐标转换到父坐标,子坐标做基于左手坐标系子->父坐标变换:先缩放后旋转再平移得到。
  Vector3 GetCameraToWorldPos(Vector3 vecCameraNodePos)
    {
        Transform cameraCtrl = GameObject.Find("CamPosCtrl").transform;
        //Transform cameraNode = Camera.main.transform; //GameObject.Find("CamPosCtrl/mainCamera").transform;
        if(cameraCtrl == null)
        {
            GSELog.LogErr("UISmallMapLogic error, CamPosCtrl GameObject is not exist.");
        }
        Vector3 cameraWorldPos = cameraCtrl.rotation * vecCameraNodePos;// cameraNode.localPosition;
        cameraWorldPos += cameraCtrl.localPosition;
        return cameraWorldPos;
    }

父子坐标系加权重的复杂物体变换,骨骼动画变换。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值