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系激活函数 传统神经网络中最常用的两个激活函数&…

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…

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

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

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

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

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…

[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;最易令人理解的思维…

北京Dotnet分享会 || 精英论坛第三期

编者按&#xff1a;没有一成不变的定律&#xff0c;没有长久不衰的流行&#xff0c;更没有一劳永逸的侥幸&#xff0c;只有自己刻苦努力、脚踏实地、兢兢业业的学习和工作&#xff0c;才会成为这个社会永远不会被淘汰的中流砥柱。一、昨夜西风凋碧树昨夜西风凋碧树&#xff0c;…

微软开源微服务运行时Dapr,赋能云原生应用开发

Dapr 是一个可移植的、由事件驱动的 Serverless 运行时&#xff0c;用于跨云和边缘构建分布式应用程序。10月9日&#xff0c;正式以 MIT 协议开源。Dapr 使开发人员能够轻松地构建弹性、无状态和有状态的微服务&#xff0c;让它们在云和边缘位置上运行&#xff0c;并包含了开发…

最大堆和最小堆

堆和栈的区别&#xff1a;一、堆栈空间分配区别&#xff1a;1、栈&#xff08;操作系统&#xff09;&#xff1a;由操作系统自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局部变量的值等。其操作方式类似于数据结构中的栈&#xff1b;2、堆&#xff08;操作系统&…

认知的高度 = 人生的高度

大家好&#xff0c;我是Z哥。我们每个人&#xff0c;每天要和很多不同的人打交道。我相信下面的场景每个程序员都有遇到过&#xff0c;业务方在某个模块下新提出了一个功能&#xff0c;但是你希望做新功能之前先把这个模块的低质量代码重构一下。但是&#xff0c;不管你怎么摆事…

VSCode开发.NETCore项目入门(1)设置中文语言环境

安装VSCode最新地址&#xff1a;https://code.visualstudio.com/&#xff0c;下载后安装即可配置语言环境打开安装好的VSCode软件&#xff0c;可以看到刚刚安装的VSCode软件默认使用的是英文语言环境&#xff0c;如下图&#xff1a;使用快捷键【CtrlShiftP】来配置&#xff0c;…

微软100题第11题

参照&#xff1a;http://blog.csdn.net/caryaliu/article/details/8107089 参照&#xff1a;http://blog.csdn.net/lalor/article/details/7626678 把二叉树看成一个图&#xff0c;父子节点之间的连线看成是双向的&#xff0c;我们姑且定义"距离"为两个节点之间的个…

.NET Core 3.0】框架之十三 || 部署攻略

本文有配套视频&#xff1a;https://www.bilibili.com/video/av58096866/?p9一、部署1、WIN_独立部署感谢群里&#xff08;白云&#xff09;小伙伴&#xff0c;博主 小淋科技 提出的方案(需要 netcore2.1 )&#xff0c;我竟然忽略了&#xff0c;该打该打&#xff0c;官档都读…

Python import以及os模块

转自&#xff1a;http://jianpx.iteye.com/blog/486466 http://blog.chinaunix.net/uid-27838438-id-4087978.html Import: 1. import 实际上是python虚拟机把当前的globals()和locals()传进__builtins__.__import__内置函数了&#xff0c;所以实际上干活的是那个__import__函…