ShaderLearning_5_坐标系变换
参考:
- 《UnityShader入门精要》冯乐乐
- 《learn OpenGL》
- 《realtime rendering》
- 原文在本地站点
http://localhost:8888/wordpress/2020/03/29/shaderlearning_5_/
本文使用的环境windows10,unity2020,vs2019
坐标空间分类
首先我们要了解一共有这下面几个空间,其中可能一个坐标空间会有多个不同的称呼
↑
图
1
展
示
的
是
O
p
e
n
G
L
O
R
G
中
对
坐
标
系
统
的
分
类
↑图1 展示的是OpenGLORG中对坐标系统的分类
↑图1展示的是OpenGLORG中对坐标系统的分类
- ModelSpace(模型空间),或者称为ObjectSpace(对象空间),或者称为LocalSpace(局部空间)
这个空间采用左手坐标系,即在unity中的x向右,y向上,z向前。这个空间的原点和坐标轴是由美工在建模软件里确定的。 - WorldSpace(世界空间)
WorldSpace就是我们口中的绝对位置,指的是在世界坐标系中的位置,通常我们把世界空间的原点放置在游戏空间的中心。WorldSpace采用左手坐标系。在坐标变换的第一步就是进行model transform。这个变换的步骤应当是得到Local相对于World的坐标,然后再将该变化左乘于LocalSpace的列向量。 - ViewSpace(观察空间),或者称为CameraSpace(摄像机空间)
这里完成的操作便是view transform。ViewSpace中原点便是摄像机位置,需要注意的是unity中ViewSpace坐标轴选择是+x向右,+y向上,+z向摄像机后方,这里采用的是右手坐标系,符合OpenGL传统,camera的正前方是-z轴方向。变化步骤同上个变化。 - ClipSpace(裁剪空间,也被称为齐次裁剪空间),用于变换的矩阵被叫做(ClipMatrix或者ProjectionMatrix)
左手坐标系,在这里要注意ProjectionMatrix有两个目的:>在这里要注意ProjectionMatrix有两个目的: 1)为投影做准备。ProjectMatrix并没有进行真正的投影,而是为投影做准备,真正的投影发生在后面,屏幕映射时候的**HomogeneousDivision(齐次除法)**过程中。而ProjectionMatrix只是将顶点的w分量改变。 2)对x,y,z分量进行缩放。使用视椎体的6个裁剪平面进行裁剪会很麻烦,在ProjectionMatrix缩放后,我们可以直接使用w分量作为范围值,如果x,y,z分量在这个范围内,就说明该顶点在裁剪空间中。 大致分为透视投影和正交投影,在这里需要补充的知识很多,请见ShderLearning_6 - ScreenSpace(屏幕空间)
左手坐标系,model transform后是裁剪,裁剪完成后进行真正的投影——将视椎体投影到屏幕空间,经过这一步变换后,我们得到真正的像素位置,而不是虚拟的三维坐标。在这一步变换中首先我们要进行HomogeneousDivision(齐次除法),也被称为PerspectiveDivision(透视除法)。便是将w分量去初一x,y,z分量。在OpenGL中我们将这一步得到的坐标叫做NormalizedDeviceCoordinates,NDC(归一化的设备坐标),透视投影的视椎体变换为裁剪空间在变换为一个立方体,同OpenGL传统,x,y,z分量的范围是[-1,1]。在DirectX中范围是[0,1]。
↑
图
2
是
透
视
投
影
齐
次
除
法
↑图2 是透视投影齐次除法
↑图2是透视投影齐次除法
↑
图
3
是
正
交
投
影
齐
次
除
法
↑图3 是正交投影齐次除法
↑图3是正交投影齐次除法
↑
图
4
是
齐
次
除
法
公
式
和
屏
幕
映
射
总
结
↑图4 是齐次除法公式和屏幕映射总结
↑图4是齐次除法公式和屏幕映射总结
总结
见下图
↑
图
5
空
间
变
换
及
旋
向
性
↑图5 空间变换及旋向性
↑图5空间变换及旋向性