super1 发表于 2022-6-21 10:50

【UE & Unity】渲染通识:几类空间的认识

在渲染管线(Render Pipeline)中,几类空间(Space)变化关系是核心基础知识之一。熟练掌握空间的应用对编写材质有着质的提示。我也是才入门渲染没几个月,最近在写学习风格化全流程的文章,写着写着觉得空间这块知识应该单独写一篇文章记录才行。写本文也算是我对空间知识的进一步深入学习和以往知识的巩固吧。
空间/坐标系

在初中数学学习坐标系的时候,我们就知道了所谓的坐标系其实就是参照对象。同一个点在不同参考系下对他的位置描述就是不同的。用下图举例:


黑点在红色坐标系的位置是(1,1),而在黑色坐标系的位置是(-2,-1).
在渲染中提到的几个空间Space,本质就是不同的坐标系。那么我们先来看一下渲染管线中的空间转换流程:


图中右侧是经常听说的顶点变换MVP矩阵。结合左侧,就知道了MVP矩阵=Projection矩阵*View矩阵*Model矩阵(矩阵相乘顺序是左乘所以是从右往左)。这张流程图就是几何阶段中顶点的完整变换过程。各个变换矩阵的推导和具体内容,我就跳过了。本文主要讲Unity&UE中常用到的几个空间和空间关系。而且,大多情况下我们都是直接用HLSL内提供的封装好的空间变换矩阵。所以并不需要完全掌握矩阵的推导过程和计算逻辑。当然,如果你是TA技美,那这个你必须得会手算推导,非常清除空间转换的逻辑。毕竟这算是基础知识。
UE,Unity常用到的空间有:模型空间,世界空间,观察(相机)空间,以及切线空间。
关于这几个空间的解释,我推荐去看Ben的解析,视频不长,视觉图画的很清晰,一目了然:View, World, Object, & Tangent Space - Shader Graph Basics - Episode 10
模型/物体/本地空间 Model/Object/Local Space

模型/物体/本地,这三类叫法指的是同一空间。我习惯叫模型空间。模型空间的坐标系原点是模型的原点。X,Y,Z三轴向量的方向和轴单位长度则以模型建模时为标准。以UE4中树模型为例:


图中的左上红框圈出的是UE中模型编辑的参照坐标系类型。现在是模型空间,则当前树的模型空间XYZ三轴方向和原点位置和中间的红框圈出的三轴线完全重合一致。如果模型旋转缩放了,那这个模型坐标系也会旋转缩放。



模型坐标系旋转

世界空间 World Space

世界空间是游戏引擎直接使用频率最高的空间。平时在gameplay逻辑代码中获取的物体绝对坐标就是世界空间系下物体的坐标。依旧以UE4中为例:


图中红框处可以看到,已经切换到了世界空间坐标系编辑。而图中显示的三轴中心是地板块的原点,又因为这个地板块世界坐标为(0,0,0),所以图中显示的就可以当作是世界空间坐标系。
相机/观察空间 Camera/View Space

相机/观察空间的坐标系原点和轴向就是相机的位置和旋转轴向。但是有一点特殊,所有空间中只有相机/观察空间是右手坐标系,其余的空间都是左手坐标系。如下图:


在UE中的View Space和Camera Space是两个空间,View Space是相对Camera Space的,他在阴影通道的表现和Camera Space略有不同。切线空间 Tangent Space

切线空间就比较特别了。他并没有参与几何阶段的顶点变换,切线空间要描述起来也比较抽象。相对其它几个空间系,他的理解成本要高一些,但是他很有用。以Ben视频中的茶壶模型为例:


切线空间不像其它空间是宏观意义的坐标系。它是对面,点的坐标系。图中放大得到的是茶壶模型的面,然后可以看到Ben在这做了个坐标系,这个就是切线空间坐标系。可以理解为每个点都有独立切线坐标系。图中红色方向是我们熟悉的法线,准确的说是这个面上某个像素的法线(Normal)。绿色的就是这个法线的切线(Tangent),蓝色的是正切线(Bitangent)。切线就是当前这个像素点的面或者顶点的切线,正切线就是法线和切线的叉乘结果向量,坐标系的3轴两两垂直。讲到现在,什么切线,正切线,都很抽象。我学的时候产生了很多问好,但当我看到切线空间的用途的时候,我一下子就悟了。
在这里我推荐去看Freya美女大佬的法线贴图,切线空间和IBL的详解:Normal Maps, Tangent Space & IBLShaders for Game Devs
看完之后,你一定会汗我一样悟出很多东西。首先,我们要明确一点:为什么要构建切线空间?是为了法线!切线空间就是为了法线而生的!
模型Model的法线表现形式是模型数据在建模软件导出时赋予的,而模型软件在导出的时候不光给出了点面的法线方向,同时还给出了切线方向。而我们通过法线和切线向量的叉乘就得到了垂直于法线和切线构成的面的正切线向量。于是,切线空间坐标系就组装完成了。切线空间和模型空间一样,都是在模型数据决定的。模型空间是宏观的,模型所有点共用一个坐标系。而切线空间是微观的,所有点各自拥有一个坐标系。知道了切线空间的坐标系的构成,那就能实现其它空间和切线空间的转换。(切线空间相关的转换矩阵,我觉得还挺难推的)
那再回到切线空间的用途:切线空间是为法线而生。直白点说,就是改变法线方向是在切线空间中完成的。我复述一遍上面Freya视频中对修改法线方向的部分:


图中白色菱形表示模型上的一个面片,蓝色箭头N就是这个面的法线向量。模型数据默认的法线是垂直这个面的。而为了在一个面上表现出坑坑洼洼,凹凸起伏的感觉,我们就需要面上的像素点的法线朝向发生改变。在三维空间中,要实现一个向量任意朝向的改变,那么至少需要加上两个非平行向量分量。为了规范,这两个分量和法线是两两垂直的。这两分量就是切线和正切线向量。上图假定红色是切线,那么绿色就是正切线。模型数据默认面的法线/切线数据都是基于顶点的法线切线。在没有法线贴图作用的情况下,模型面上的法线数据=(0,0,1),而当使用了法线贴图,法线方向就变成了贴图采样像素解包后的(r,g,b)(法线贴图是颜色通道值,在范围;而向量分量范围在[-1,1],这样才能保证向量方向的自由改变),如下图:


和Z轴重合的深灰色向量是没有使用法线贴图的默认面法线,紫色的是读取了法线贴图数据过后的新法线向量。如此一来我们就实现了对面上像素点的法线方向修改。
综上所述,可以明显看得出来切线空间就是基于物体点面法线而构建的。基于切线空间,我们可以实现在不增加模型顶点数量的情况下,增加模型表面的光照细节;也可以实现面上细节的层次叠加,如岩石上层分布苔藓等。
关于法线贴图的颜色数据解包其实很简单。就是把RGB的范围映射到[-1,1],我们只需要对R,G,B值进行(r/g/b) * 2 - 1的计算就可以了。总结

在UE,Unity中,编写材质的时候,大多情况并不太需要非常熟悉各个空间转换的计算过程。这些变化大多都已经封装好。认识透各个空间的坐标系和他们的相对关系基本就足够用了。
页: [1]
查看完整版本: 【UE & Unity】渲染通识:几类空间的认识