天天看点

unity3d:渲染流水线

https://www.jianshu.com/p/2d8eeec9d0ef

unity3d:渲染流水线

应用阶段

本阶段主要是将与渲染有关的场景数据包括:模型图元数据、光源数据、摄像机数据传递到几何阶段。这个阶段是在CPU中进行的,因此可以由程序员全权控制,比如应用一些算法对渲染性能做一些优化。

备注:图元:构成模型的基本单元,点、线、三角形。图元的基本单元是顶点。

概括:此部分由CPU主导。在此部分可以设置场景设置,防止模型,放置摄像机以及灯光

几何阶段:

主要是将模型的顶点数据包括位置信息和着色信息转换到屏幕空间。此后的阶段都是位于GPU中,一部分是可由程序员编程的,一部分是高度可配置的,还有一部分是设备自身决定。

概括:顶点着色器->曲面细分着色器->几何着色器->裁剪->屏幕映射。此阶段的任务是将上一阶段传递过来的数据,即最基本的顶点信息由模型空间坐标系转换到屏幕坐标系下。

由于曲面细分着色器和几何着色器是可选着色器,前者用于细分图元,后者进行逐图元着色。所以此阶段可以简单理解为顶点着色->裁剪->屏幕映射。

顶点着色:

任务有两个:

1、 通过坐标转换将模型的顶点位置数据转换到视图空间。主要是下面4个空间坐标

1.Object space —— 模型坐标空间

2.World space —— 世界坐标空间,

3.Eye space —— 观察坐标空间

4.Clip and Project space —— 屏幕坐标空间

首先顶点着色阶段拿到的顶点坐标数据都是位于模型空间的,要经过模型转换将这些坐标数据转换到世界空间。接着为了方便后面的投影和裁剪,需要将坐标数据从世界空间转换到摄像机空间(摄像机位置为原点,x轴指向右方,y指向上方,z轴是背离摄像机朝向的方向),这称为视图转换。模型转换和视图转换都可以用4x4的矩阵进行操作。

Q:模型空间,世界空间,观察坐标空间,裁剪与平面空间(屏幕坐标空间)是什么

A:模型空间:也称为对象空间,即模型的局部坐标系。

其实就是模型在建模时建立的一个与其他物体没有任何参照关系的基于自己原点的三维坐标空间,包含模型的顶点值。模型坐标空间对于操作模型自身属性比较实用,但当空间中有许多个物体,为了表达各个物体间的相对关系,由于模型坐标空间不包含与任何物体的参照关系,所以这里我们需要引用一个统一的空间坐标,每个物体在这个坐标中都有一个自己的相对于此坐标原点的确定坐标位置,这个坐标空间就是World space(世界坐标空间)。

世界空间:即所有模型所在的统一坐标系。

观察空间:即摄像机空间,对应摄像机坐标系,存在正交相机坐标系和透视相机坐标系。

在计算机中,每次只能从唯一的视角触发渲染物体。在游戏中,引入了视点漫游的功能,屏幕中显示的内容随着视点的变化而变化。这些都是因为GPU将物体顶点坐标从world space转换到了eye space。

Eye space(视点坐标空间),即以Camera(视点或相机)为原点,由视线方向、视角和远近平面,共同组成的一个梯形体的三维空间,称之为viewing frustum(视锥体),如下图所示:      

远近平面:近平面,是梯形体中较小的矩形面,作为投影平面;远平面,是梯形体中较大的矩形。在这个梯形体中的所有顶点数据都是可见的,而超出这个梯形体之外的场景数据,会被视点去除(Frustum Culling,也称为视锥裁剪)。

屏幕空间:最终形成的图像显示屏幕空间。

一旦顶点坐标被转换到eye space中,就需要判断哪些点是视点可见的。位于视锥体以内的顶点为可见,以外的则为不可见的,会被视点去除。这个步骤就是clip(裁剪),识别指定区域内或者区域外的图形部分的过程称之为裁剪算法。

裁剪算法包括:视域裁剪(View Frustum Culling)、背面剔除(Back-Face Culling)、遮挡剔除(Occlusing Culling)和视口裁剪等。      

Q:光栅化阶段背面剔除

unity着色器内的Cull命令一共有三个,Cull Back(默认),Cull Front,Cull Off

Cull Front是剔除正面,该命令可以让我们看到背面,在透明效果中,比如一个立方体,如果我们希望看到立方体的正面和背面,就需要使用到这个命令,不是Cull Off命令,因为透明效果需要关闭深度检测,使用Cull Off会导致渲染顺序出错,这个后面还会讲到。

Cull Off是关闭剔除,这个命令可以让我们看到正面和背面,但也会带来比较大的花销;

对于一个平面而言,Cull Off可以让我们看到背面;但是对于一个立方体而言,Cull Off还是没能让我们看到背面,这是因为片元还要经历深度测试,一般来说除了平面之外,其它三维物体即使关闭了剔除,它的背面也会由于深度检测被剔除掉,而且我们往往不需要看到背面。所以Cull Off命令通常用在我们需要在场景中同时看到正面和反面,比如将plane用作楼层地板、墙板等;

裁剪的具体实现是在一个单位立方体中进行的,该立方体的对角顶点分别是(-1,-1,-1)和(1,1,1),通常称这个单位立方体为规范立方体(CVV)。CVV的近平面(梯形体中较小的矩形面)的XY坐标对应屏幕像素坐标(左下角为0,0),Z坐标则代表画面像素深度。多边形的裁剪就是在CVV中完成的。

此阶段坐标变换的目的就是将顶点从模型空间转换到裁剪空间,这也是顶点着色器最基本的任务。也可以在此阶段输出顶点的纹理坐标uv

2、计算顶点着色数据。

应用材质,灯光等数据计算出顶点的着色数据,并储存在顶点中。当然这里也可以不用计算任何着色数据,把着色信息存储在顶点中,传递后后续阶段进行处理。

这一阶段是可由程序员编程的,称为顶点着色器。程序员可以自由决定顶点着色的方程式,也可以不处理,只是将着色数据传递到下面阶段。并且,程序员可以在位置变换上做手脚,使模型的位置信息灵活多变,产生一些独特的效果,甚至可以做动画(顶点动画)。

顶点动画(典型应用:旗子飘舞,摇摆的小草,水波飘荡)

Q:shader中顶点位移,缩放,旋转

A:shader 中进行顶点计算,只动顶点数据,模型自身不会旋转​

投影:

使用最多的两种投影方式是:透视投影和正交投影。为了方便裁剪,无论采用哪种投影方式,摄像机空间的数据最终会统一转换到单元立方体呢。这个过程称为投影转换,最终物体处于裁剪空间也叫齐次空间。

裁剪空间与齐次空间

裁剪:

只有摄像机视锥体内的物体才是可见的。视锥体已经转换成了单元立方体,因此只有位于单元立方体内部的图元才会保留,位于外部的会被舍弃,相交的图元会被裁剪。

屏幕映射:

将上述保留下来的图元映射到屏幕上。这个过程基本上是一个缩放的过程,将单元立方体中的图元,根据屏幕大小,得到图元的屏幕坐标,注意屏幕坐标是二维的,屏幕坐标和z轴构成了窗口坐标系,xy轴储存着屏幕的位置,z轴储存着深度值,深度值主要是表示物体的遮挡关系。

光栅化:

有关术语:片元:独立的一块片段数据,储存着着色信息和深度值。会与屏幕的像素进行比较,最后影响屏幕上的像素颜色。

颜色缓冲区:一块内存,存储着屏幕上每块像素的颜色。

深度缓冲区:一块内存,存储着屏幕上每块像素的深度。

主要是将屏幕上的顶点数据转换成像素数据。

三角形设置:

每三个顶点形成一个三角形。为了后续阶段的计算,会根据顶点的信息以及一些方程计算出三角形边界的信息。

三角形遍历:

遍历所有的三角形,根据上述边界信息,计算其覆盖的像素,并且会生成一个片元。片元中保存着着色信息,以及深度信息。这些数据是通过三角形三个顶点数据的插值运算得到的。

注意:片元并不是像素,像素是屏幕上显示颜色的单元,片元只是保存了像素的数据。

像素处理阶段

将片元与原有的像素合并输出到屏幕上。

像素着色:

合并: