[UnityShader基础]坐标系


本文转自大神:Rocky Lai 的技术博客,请点击链接查看原文,尊重楼主大大版权。

3D坐标系

这节从很平常一段对话开始:

甲跟乙说: 喂,你看到那个人没有?
乙: 你说的是哪个?
甲: 就是那棵树旁边那个。

从对话里面我们知道:要描述一个物体的位置,我们需要借助参照物。 其实甲也可以这么说:

甲: 在那个个子很高的人左手边那位。

所以说 参照物是可以选择的,可变的

我们把上面对话推广到坐标系上,来给坐标系下个山寨的定义:坐标系是为了描述物体位置而存在,我们借助的参照物是它的原点。由于可以选择不同的参照物,所以我们可以选择不同的原点。 原点很重要,我们利用坐标系的时候首先要知道原点在哪里。

既然原点可以任意选,那不是说会出现很多坐标系? 是的,但是我们使用几种约定的坐标系就好了。

那些坐标系们
下面是我们平时会碰到的一些坐标系。按规定,原点的各个轴是数值都是 0 来表示。

  • 物体坐标系 (Object Space): 有时也叫做 Local Space。是 3D 模型内部的坐标系,原点 (0, 0, 0) 一般是模型中心。
  • 世界坐标系 (World Space): Unity 系统中的绝对坐标系,原点是在场景的 (0,0,0) 位置处。
  • 视口坐标系 (Viewport Space): 以摄像机为原点,朝向为 Z 轴的坐标系。原点 (0, 0, 0) 是摄像机的位置。
  • 屏幕坐标系 (Screen Space): 原点 (0, 0) 在屏幕的左下角,右上角为 (Screen.width,Screen.height)

那问题来了。这些坐标系们有什么关系?

我们以立方体为例。我们从 渲染管线小节中知道,Mesh Renderer 组件得到模型数据之后它会执行 vertex shader(Unity 默认的 Shader 给我提供了)。vertex shader 里面做了下面这些事:

  1. 先把立方体从模型的物体坐标系转换成世界坐标系,从 物体 到 世界。这样子,它和摄像机(世界坐标)的位置就用同一个坐标系描述了。
  2. 再把立方体从世界坐标转换成视口坐标系,也就是摄像机因为原点的坐标系,从 世界 到 视口。这样它是在摄像机的正面,还是在反面了。
  3. 最后在投射到屏幕坐标系上, 从 视口 到 屏幕。这样知道哪些区域需要绘制在屏幕上,哪些不需要。
    总结上面一系列变换关系就是: 物体 到 世界 再到 视口 再到 屏幕。中间经过了三次变换 (transform)。这些变换在数学上通过 矩阵 来描述的。这里有个知识点:矩阵可以表示变换。在这里推荐关于 3D 数学的一本经典好书 《3D数学基础图形与游戏开发》

到现在是不是有种跃跃欲试,但是想想又头大的感觉,在 Unity 里面这些矩阵具体的数值是什么?要是自己去运算那多复杂啊。别急,Unity 给我们已经提供了这些矩阵当作 Shader 的内置变量(详情参考这个链接),可以在编程的时候直接使用。在这里只是说一下,我们利用 UNITY_MATRIX_MVP 这个矩阵就可以达到变换到屏幕坐标系的目的。至于怎么做,会在以后的文章中会提到。

左手和右手坐标系
这两不是新坐标系,是建立三维坐标系的两种选择。换句话说对于处于同一个物体,可以用基于左手坐标系规则来建立三维坐标系,也可以用基于右手坐标系规则来建立三维空间,他们的区别是坐标轴的数值会有差异。

为什么叫做左手和右手,看看下面的图就知道了。

一般情况下左手和右手坐标系的数值做转换的话只需把 Z 值乘以 -1 即可。比如左手坐标系的 (1, 1, 1) 转成为右手坐标系是 (1, 1, -1)

转载自:https://blog.csdn.net/qq_33337811/article/details/78576395

You may also like...