Shader 坐标转换

转自: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图形学里一样,只是多了一维坐标,一般的变换矩阵如下图所示:
    matrix
    单独平移矩阵和缩放矩阵如下图所示,也比较好理解,其中Tx,Ty,Tz分别表示在各个坐标轴上平移的距离,Sx,Sy,Sz分别表示在各个坐标方向上缩放的倍数。
    TranScale
    旋转矩阵在理解上需要一点点推导,以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轴方向旋转的变换矩阵:
    Rotation 
    另外3维空间下围绕任意轴旋转的旋转变换矩阵是通过平移矩阵和围绕各个轴旋转的矩阵复合而得出的。
    在世界坐标系里的任何一个模型的状态都可以通过若干中变换矩阵的组合来表明它的唯一状态,通过矩阵相乘来得到最终的变换矩阵,需要注意的是因为所有的变换矩阵都是相对坐标系的原点完成的,所以变换矩阵相乘时候的顺序关系很重要,相互颠倒会产生完全不同的变换矩阵。
    视角变换
    通过世界变换,我们将所有的模型都转换到一个统一的世界坐标系中,但是在游戏中我们的观察点不可能总是世界坐标系的原点,面向着Z轴的正方向。摄像机和模型是同样可以游离于场景中的任何地点,面向任意角度的,所以这就需要通过视角变换来实现。
    一个视角变换通常是由一次平移变换和三次旋转变换来完成的,平移矩阵负责将相机从默认的世界坐标系的原点平移到正确的位置,三次旋转分别负责围绕三个坐标轴的旋转,将相机调整至正确的朝向。
    说的很抽象,但实际上可以理解为将转换到世界坐标下的各个模型再转换到以摄像机为原点的摄像机坐标系下,当然在游戏中是不需要手动生成这个矩阵的,我们只需要提供相机的位置,朝向等等参数,API会帮我们生成正确的视角矩阵。
    投影变换
    投影变换的工作就是将摄影空间中的三维物体投影到二维的平面上,逻辑上也就是用户的屏幕区域。这种三维到二维的变换过程就是投影变换,即从取景空间到投影空间的变换。
    投影变换分为两种基本的投影变换:正交投影和透视投影
    正交投影中,投影向量和观察平面垂直,物体坐标沿观察坐标系的Z轴平行投影到观察平面上,观察点和观察平面间的距离不会影响物体的投影大小。工程设计中的顶视图、前视图和侧视图就是典型的正交投影,正交投影没有透视关系,可以利用正交投影来完成D3D渲染2D游戏画面。
stretch    而透视投影实现的是一个缩放、透视的投影。透视投影的特点是:距离摄像机越远的物体在投影平面上的成像越小。更像人眼所能看到的现实世界中的透视关系。
    下面我们来根据透视投影的几何关系来推导一下透视投影下的投影矩阵的生成:
    在游戏中,当以透视的方法从摄像机来观察场景的时候,会在场景内形成一个金字塔形状的可见区域,又因为远近两个裁剪面的存在,所以实际上可见区域是一个截体,透视投影矩阵的作用是将这个取景截体转换成一个立方体(将近摄像机端拉伸),分别将X和Y坐标映射到投影平面的正确的位置上,同时保持深度信息不变,因为截体的近端比远端小,所以靠近摄像机的对象将被放大,而远离摄像机的对象,则会相对保持原样。

projection     到齐次裁剪空间的映射是通过一个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’。根据两个平面内坐标同平面的线性比例关系,我们继续推导:
    transtui2
    Z轴的线性关系相对简单,但是因为在光栅化过程中为避免透视失真而进行的乘以z倒数的插值操作(显卡的工作,为什么要这样的具体原理还理解不够透彻,以后补齐),所以这里要建立关于1/z的映射,这样就可以对投影深度值进行线性插值了:
    transtui3
    将所得的x’,y’,z’同Px,Py,Pz所对应的关系进一步整理,就可以得到最终的正确的投影矩阵了。这个投影矩阵也是D3D中所用的投影矩阵,虽然我们通常都是提供相机的fov,朝向,位置等参数利用API生成, 但是理解原理是非常重要的,关于正交投影的投影矩阵大家也可以利用类似的步骤推导出来。
    transtui4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313349.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

致所有.Net者和有梦想的朋友们 - 共勉

这篇文章很早就想写的了,主要是人到了一定的年纪,就想唠叨一些看法,认不认可不重要,重要的是生活给予你的酸甜苦辣,你都想一吐为快。 这里主要基于多年来自己的一个行业感受和以及生活感想,唠叨一下工作以及…

ReLU的起源

论文参考:Deep Sparse Rectifier Neural Networks 网页参考:http://www.mamicode.com/info-detail-873243.html 起源:传统激活函数、脑神经元激活频率研究、稀疏激活性 传统Sigmoid系激活函数 传统神经网络中最常用的两个激活函数&…

二叉树的锯齿形层次遍历

1、题目描述 给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。 例如: 给定二叉树 [3,9,20,null,null,15,7], 3/ \9 2…

Asp.NET Core 轻松学-项目目录和文件作用介绍

前言上一章介绍了 Asp.Net Core 的前世今生,并创建了一个控制台项目编译并运行成功,本章的内容介绍 .NETCore 的各种常用命令、Asp.Net Core MVC 项目文件目录等信息,通过对命令的学习和操作,对项目结构的认识,进一步理…

Dubbo 常见服务治理策略

1、Dubbo体系结构 2、Dubbo容错机制 Dubbo集群容错架构图 各节点关系: 这里的Invoker是Provider的一个可调用Service的抽象,Invoker封装了Provider地址及Service接口信息。Directory代表多个Invoker,可以把它看成List,但与Lis…

Python 依赖库

ImportError: No module named cv2 解决方法import cv2时会出现这个问题 解决方法:将openCV安装目录里的python文件夹内的cv2.pyd复制到Python安装目录里Lib中site-packages内即可解决. 当然 要注意32位还是64位。 ImportError DLL load …

IT技术人员的35个特点,你占几个?

作者:zollty,资深程序员和架构师,私底下是个爱折腾的技术极客,架构师社区合伙人!1、价值观对生活的一般看法:追求简单,安定,可控制的生活,但对家庭生活的责任持消极态度草…

ReentrantLock可重入锁使用及原理

使用场景:https://www.cnblogs.com/XJJD/p/8758713.html 原理实现:https://blog.csdn.net/weixin_39910081/article/details/80147754

LNK2001

转载自 http://bbs.csdn.net/topics/100140880 学习VC++时经常会遇到链接错误LNK2001,该错误非常讨厌,因为对于 编程者来说,最好改的错误莫过于编译错误,而一般说来发生连接错误时,编译都已通…

asp.net core 腾讯验证码的接入

asp.net core 腾讯验证码的接入Intro之前使用的验证码服务是用的极验验证,而且是比较旧的,好久之前接入的,而且验证码服务依赖 Session,有点不太灵活,后来发现腾讯也有验证码服务,而且支持小程序&#xff0…

Spring boot 启动过程

先Mark, https://www.cnblogs.com/trgl/p/7353782.html https://blog.csdn.net/zl1zl2zl3/article/details/79765725 https://blog.csdn.net/u010811939/article/details/80592461 https://www.jianshu.com/p/dc12081b3598

ffmpeg加环境变量

转自:http://blog.csdn.net/leixiaohua1020/article/details/19016469 FFMPEG是命令行工具,因此使用起来多少还是会有些不方便。在这记录两点方便使用FFMPEG的方法: 1.任何目录下都可以使用FFMPEG 问题描述:需要转码(播…

.NET Core 微信公众号小程序6种获取UnionID方法,你知道哪几种?

前言获取UnionID是开发微信公众号/小程序中很有必要的一个环节,特别是针对一个公司拥有多个公众号小程序而推出的机制,实现打通账户一体化,用UnionID来区分多平台的唯一性。官方的解释:如果开发者拥有多个移动应用、网站应用、和公…

.NET LINQ分析AWS ELB日志避免996

前言小明是个单纯的 .NET开发,一天大哥叫住他,安排了一项任务:“小明,分析一下我们 超牛逼网站上个月的所有 AWS ELB流量日志,这些日志保存在 AWS S3上,你分析下,看哪个 API的响应时间中位数最长…

网络摄像头实时获取信息

转自&#xff1a;http://blog.csdn.net/yong_hen/article/details/42460387#quote 转自&#xff1a;http://blog.csdn.net/leo2007608/article/details/9885219 代码&#xff1a; openCV版本&#xff1a;2.4.10. 平台&#xff1a;win7 [cpp] view plaincopy #include <op…

微软100题第4题

转载自&#xff1a;http://blog.csdn.net/luxiaoxun/article/details/7537605 主要技术含量在于vector的使用(可变尺寸数组)和栈的概念。 题目&#xff1a;输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相…

相同类方法之间调用,注解失效的问题

问题&#xff1a; 在Spring管理的项目中&#xff0c;方法A使用了Transactional注解&#xff0c;试图实现事务性。但当同一个class中的方法B调用方法A时&#xff0c;会发现方法A中的异常不再导致回滚&#xff0c;也即事务失效了。 原因&#xff1a; Transactional是Spring提供…

[ASP.NET Core 3框架揭秘] 依赖注入:依赖注入模式

IoC主要体现了这样一种设计思想&#xff1a;通过将一组通用流程的控制权从应用转移到框架之中以实现对流程的复用&#xff0c;并按照“好莱坞法则”实现应用程序的代码与框架之间的交互。我们可以采用若干设计模式以不同的方式实现IoC&#xff0c;比如我们在前面介绍的模板方法…

微软100题第5题

转载自&#xff1a;http://blog.csdn.net/littlestream9527/article/details/8104731 http://blog.csdn.net/v_july_v/article/details/6370650 http://blog.csdn.net/insistgogo/article/details/7689297 下面&#xff0c;我试图用最清晰易懂&#xff0c;最易令人理解的思维…

大样本统计

题目描述 我们对 0 到 255 之间的整数进行采样&#xff0c;并将结果存储在数组 count 中&#xff1a;count[k] 就是整数 k 的采样个数。 我们以 浮点数 数组的形式&#xff0c;分别返回样本的最小值、最大值、平均值、中位数和众数。其中&#xff0c;众数是保证唯一的。 我们…