转自:http://www.ownself.org/blog/2010/kong-jian-zuo-biao-zhuan-huan.html

这个比较基础了,不过基础最重要,往往应该理解透彻,并且反复复习。

我们知道在3D画面渲染过程中对于模型的计算的一部分被称为Transforming and Lighting(T&L)阶段,其中Lighting表示光照,而Transforming就是指的坐标变换,这两部分的计算也是3D场景中计算最重要基础的一步。
    空间坐标变换主要的工作就是将处于局部坐标系的模型转换到用户屏幕所在的屏幕坐标系内。
    而这个过程的计算上主要是来自线性代数中的知识,我们知道在线性代数中,线性的变换是可以用矩阵来表示的,而通过将向量[x,y,z,w]同变换矩阵相乘即可完成相应的变换,这正是我们实现空间坐标变换的数学基础,在3D图形学中,空间坐标变换一般分为三个步骤——世界变换、视角变换、投影变换,而完成这些变换就是由矩阵运算来完成的。
    世界变换
    我们知道所有模型都是独立创建的,他们拥有自己独立的一个局部坐标系来描述模型内部各个面片顶点之间位置的关系,当我们将这些模型放在一起来组建游戏场景的时候,逻辑上他们就处在了同一个坐标系内来描述模型与模型之间位置与角度的关系,这个坐标系我们所说的世界坐标系,而将模型中的每一个顶点从局部坐标系转换到世界坐标系的过程,我们称之为世界变换。
    世界变换是通过将模型中每一个顶点乘以世界变换矩阵来完成的,通常情况下这个世界变换矩阵是通过一系列变换矩阵的结合形成的一个包含了所有变换内容的矩阵来完成计算的,包括平移、旋转、缩放等等变换。
    在3D图形学里的矩阵变换同2D图形学里一样,只是多了一维坐标,一般的变换矩阵如下图所示:
   
    单独平移矩阵和缩放矩阵如下图所示,也比较好理解,其中Tx,Ty,Tz分别表示在各个坐标轴上平移的距离,Sx,Sy,Sz分别表示在各个坐标方向上缩放的倍数。
   
    旋转矩阵在理解上需要一点点推导,以2维空间下围绕原点旋转为例,大家可以画一个草图来帮助推导,设点(x,y)与原点的连线同X轴的角度为b,以此方向继续旋转a度,至点(x’,y’),我们可知旋转轨迹所在圆的半径R=x/cosb,R=y/sinb。而x’=R*cos(a+b),y’=R*sin(a+b),根据合角公式拆开,再将前面的式子带入,可得x’=xcosa-ysina;y’=xsina+ycosa。
    3维空间下以此相推可分别得出围绕X轴方向旋转、围绕Y轴方向旋转、围绕Z轴方向旋转的变换矩阵:
     
    另外3维空间下围绕任意轴旋转的旋转变换矩阵是通过平移矩阵和围绕各个轴旋转的矩阵复合而得出的。
    在世界坐标系里的任何一个模型的状态都可以通过若干中变换矩阵的组合来表明它的唯一状态,通过矩阵相乘来得到最终的变换矩阵,需要注意的是因为所有的变换矩阵都是相对坐标系的原点完成的,所以变换矩阵相乘时候的顺序关系很重要,相互颠倒会产生完全不同的变换矩阵。
    视角变换
    通过世界变换,我们将所有的模型都转换到一个统一的世界坐标系中,但是在游戏中我们的观察点不可能总是世界坐标系的原点,面向着Z轴的正方向。摄像机和模型是同样可以游离于场景中的任何地点,面向任意角度的,所以这就需要通过视角变换来实现。
    一个视角变换通常是由一次平移变换和三次旋转变换来完成的,平移矩阵负责将相机从默认的世界坐标系的原点平移到正确的位置,三次旋转分别负责围绕三个坐标轴的旋转,将相机调整至正确的朝向。
    说的很抽象,但实际上可以理解为将转换到世界坐标下的各个模型再转换到以摄像机为原点的摄像机坐标系下,当然在游戏中是不需要手动生成这个矩阵的,我们只需要提供相机的位置,朝向等等参数,API会帮我们生成正确的视角矩阵。
    投影变换
    投影变换的工作就是将摄影空间中的三维物体投影到二维的平面上,逻辑上也就是用户的屏幕区域。这种三维到二维的变换过程就是投影变换,即从取景空间到投影空间的变换。
    投影变换分为两种基本的投影变换:正交投影和透视投影
    正交投影中,投影向量和观察平面垂直,物体坐标沿观察坐标系的Z轴平行投影到观察平面上,观察点和观察平面间的距离不会影响物体的投影大小。工程设计中的顶视图、前视图和侧视图就是典型的正交投影,正交投影没有透视关系,可以利用正交投影来完成D3D渲染2D游戏画面。
    而透视投影实现的是一个缩放、透视的投影。透视投影的特点是:距离摄像机越远的物体在投影平面上的成像越小。更像人眼所能看到的现实世界中的透视关系。
    下面我们来根据透视投影的几何关系来推导一下透视投影下的投影矩阵的生成:
    在游戏中,当以透视的方法从摄像机来观察场景的时候,会在场景内形成一个金字塔形状的可见区域,又因为远近两个裁剪面的存在,所以实际上可见区域是一个截体,透视投影矩阵的作用是将这个取景截体转换成一个立方体(将近摄像机端拉伸),分别将X和Y坐标映射到投影平面的正确的位置上,同时保持深度信息不变,因为截体的近端比远端小,所以靠近摄像机的对象将被放大,而远离摄像机的对象,则会相对保持原样。

     到齐次裁剪空间的映射是通过一个4×4的投影矩阵实现的。在这个投影矩阵中,除了其他的变换功能外,还要保证变换后的点w坐标等于摄像机空间中的点的z坐标的负值,这样,将变换后的点的坐标分量除以w坐标后,就可以生成裁剪空间中相应的三维点。
    我们设图中可视区中一点P(Px,Py,Pz),将P点同摄像机相连同投影面交于一点(x,y,z),这个点就是投影变换后P所应该在的点,远近裁剪面到摄像机的距离分别是d和Zf。根据相似三角形,我们可以知道x=d*Px/Pz;y=d*Py/Pz,设投影平面的四个边框的横纵坐标位置分别是r,l,t,b(右左上下)。为了满足取景截体到齐次空间的映射,我们还需要需要将投影后的x,y坐标映射到[-1,1]区间,而通常的,将z坐标映射到[0,1]区间,映射后的坐标为x’,y’,z’。根据两个平面内坐标同平面的线性比例关系,我们继续推导:
   
    Z轴的线性关系相对简单,但是因为在光栅化过程中为避免透视失真而进行的乘以z倒数的插值操作(显卡的工作,为什么要这样的具体原理还理解不够透彻,以后补齐),所以这里要建立关于1/z的映射,这样就可以对投影深度值进行线性插值了:
   
    将所得的x’,y’,z’同Px,Py,Pz所对应的关系进一步整理,就可以得到最终的正确的投影矩阵了。这个投影矩阵也是D3D中所用的投影矩阵,虽然我们通常都是提供相机的fov,朝向,位置等参数利用API生成, 但是理解原理是非常重要的,关于正交投影的投影矩阵大家也可以利用类似的步骤推导出来。
   

Shader 坐标转换相关推荐

  1. java ndc_【Unity Shader】从NDC(归一化的设备坐标)坐标转换到世界坐标的数学原理...

    从NDC(归一化的设备坐标)坐标转换到世界坐标要点 参考资料 How to go from device coordinates back to worldspace http://feepingcr ...

  2. 使用opengl编程实现一个三维渲染实体_Unity Shader学习随记_01_渲染流水线

    什么是Shader?它和Material(材质)的关系 Shader,中文翻译:着色器,是可编程图形管线的算法片段 Shader实际上就是一小段程序,它负责将输入的顶点数据以指定的方式和输入的贴图或者 ...

  3. 偏移shaderuv_Unity Shader 之 uv动画

    Unity 动画 Unity Shader 内置时间变量 引入时间变量 名称 类型 描述 _Time float4 t是自该场景加载开始所经过的时间,4个分量分别是(t/20, t, 2t, 3t) ...

  4. GPU Shader 程序调试方法

    转载自: http://blog.csdn.net/pizi0475/article/details/7573939 内容提要:手动调试和使用工具PIX调试Direct3D程序. 3D绘图中常见问题: ...

  5. Vertex and Fragment Shader

    Semantics语义词: 定义:GPU工作时,数据通常暂存在寄存器,那么在Cg中,语义词就指定了输入/输出数据和图形硬件寄存器之间的映射关系. 原理:根据输入语义,图形处理器从某个寄存器取数据:然后 ...

  6. Unity Shader入门精要 第2章 读书笔记

    第2章  渲染流水线 注意:图片的来源基本来自作者冯乐乐的GitHub,感谢作者分享 https://github.com/candycat1992/Unity_Shaders_Book 什么是Sha ...

  7. Unity 3D 图形学 Shader之顶点与片段着色器(五)

    通过实现一个只有颜色属性可调节的简单材质效果更好的了解顶点与片段着色器 一.顶点着色器 顶点着色器就是处理顶点的着色器,每个顶点都会执行一次顶点着色器.我们先认识下顶点函数的结构: 顶点着色器函数的名 ...

  8. OpenGL学习笔记——坐标转换

    因为OpenGL中的坐标转换有些复杂,所以做一篇笔记记录一下. 文章目录 一.简介 二.代码实现 2.1简单的测试 2.2旋转测试 三.小结 一.简介 学习OpenGL一段时间之后,数据的坐标转换将会 ...

  9. Unity Shader知识点(二)写一个基础漫反射Shader

    前言 我们刚学习Shader时,往往会被计算机图形学相关复杂的数学.物理知识所困扰,并在学习过程中丧失兴趣.个人以为,在代码以外,学习Shader应当有本科线性代数课程基础的概念框架,在这一基础上,完 ...

最新文章

  1. 单片机c语言NTC温度查表程序,STM32查表法读NTC值并显示温度
  2. 如何修炼成某一领域的高手
  3. linux运维、架构之路-Zabbix监控
  4. JSP中get和post请求方式的区别及乱码解决方法
  5. Oracle 表备份还原
  6. 利用bobo-browse 实现lucene的分组统计功能
  7. 在线YAML转TOML工具
  8. IOS开发--网络篇--GET请求和POST请求
  9. ffmpeg 音乐循环_背景音乐自动循环播放
  10. java开发之权限管理详解
  11. delphi多线程TThread详解
  12. 【引用】男人爱你的三个细节
  13. ME525+刷机2.3.6版本过程分享
  14. 狗是人类最忠诚的伙伴,当狗遇到不同的人会有不同的反应,下面要求编写一个案例模拟狗遇到不同的人时的反应。
  15. 半群 群 阿贝尔群 环 整数环 多项式环
  16. 电影网站 php asp,asp电影网址导航大全 V20201218
  17. 【Procmon教程2】如何揪出篡改注册表的元凶?
  18. P3437 [POI2006]TET-Tetris 3D
  19. Python+pywin32批量读取带密码的Excel文件数据导出为CSV文件
  20. MOOC《基础和声》笔记

热门文章

  1. 【iVX 初级工程师培训教程 10篇文拿证】02 数值绑定及自适应网站制作
  2. 计算机专业技能考核方案,计算机专业技能课教学目标考核方案教程.doc
  3. mysql 开发规范_专业级的MySQL开发设计规范及SQL编写规范
  4. 06-广度优先搜索:图、队列
  5. 趣图:脸部识别最快的实现
  6. 有哪些命令行的软件堪称神器?
  7. mysql连接指定时区_MySQL创建JDBC连接时区问题
  8. python input函数无法输入字符串_Python手把手教程之用户输入input函数
  9. 电影特效用到什么计算机知识,后期影视特效处理知识普及
  10. js 上下箭头滚动_JS中的this完全讲解,再也不会被this搞晕了