unity3d:渲染流水线

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

在这里插入图片描述

应用阶段

本阶段主要是将与渲染有关的场景数据包括:模型图元数据、光源数据、摄像机数据传递到几何阶段。这个阶段是在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:光栅化阶段背面剔除
A:https://blog.csdn.net/qq_36383623/article/details/97178579
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 中进行顶点计算,只动顶点数据,模型自身不会旋转
https://blog.csdn.net/zhangxiao13627093203/article/details/81204856

投影:

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

裁剪:

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

屏幕映射:

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

光栅化:

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

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

三角形设置:

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

三角形遍历:

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

像素处理阶段

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

像素着色:

逐片元的操作,这里跟顶点着色一样属于可编程的,也称为片元着色器(像素着色器)。这里主要作用跟顶点着色很像,计算着色信息,但是主角变了,顶点着色器主要作用于顶点,片元着色器主要作用于片元。可以运用各种计算方式,以及技术,比如贴纹理(图片),重新生成片元的颜色信息。

合并:

合并是指的,前一阶段得到的片元与对应的屏幕像素进行合并。那么具体的合并是怎么操作的?主要的步骤有两个:
1、测试。测试是决定哪些片元有资格与像素颜色合并,哪些片元需要被舍弃掉。
2、合并。将片元颜色与对应的像素颜色合并。具体的合并方式是高度可配置的。我们可以决定直接替换掉原有颜色,也可以用一定的规则混合两个颜色。
有一个算法叫z算法,也称为深度测试。每块像素的颜色储存在颜色缓冲区,深度值储存在深度缓冲区。同时片元中保存着有新的颜色值和深度值,首先深度值会与屏幕上像素的深度值进行比较,如果片元深度值小于屏幕上像素的深度值,那么就代表当前片元是比屏幕上对应的像素要离摄像机更近,此时就是把片元的颜色信息赋值给屏幕对应像素的颜色缓冲区,深度值赋值给屏幕对应像素的深度缓冲区;如果大于屏幕上像素的深度值,那么该片元就不会影响屏幕上的像素信息。这么做保证了渲染出来的画面永远都是摄像机视角可见的元素,被遮挡的物体就被替换了。上述过程是无视渲染顺序的。因此也就有了z算法的一个重大缺点就是处理透明度。
假设屏幕上已经存在一个物体的渲染,接下来要渲染一个透明的物体,这个物体恰好位于已渲染的物体像素上,那么根据z算法要将当前的透明物体的信息覆盖到已有的物体信息。实际生活中,这种情况下,透明物体后面的物体还是可以看得到的,所以仅仅使用z算法不做处理的话,就会得到错误的视觉答案。
好在我们有其他的处理办法。
Alpha通道与颜色缓冲区有紧密联系。我们可以在片元着色器中决定弃除不想要的片元。可以用这种方式设置标准值,所有的片元的Alpha通道都会与该值比较,通过就可以参与后续操作,不通过就可以直接丢弃,不影响屏幕上原有的像素,这个过程称为Alpha测试。
当然还是会存在一定的问题,生活中完全透明的物体几乎不存在,大多都是以半透明的形式存在,比如透过绿色玻璃可以看到后面的物体,首先绿色玻璃是我们可以看得到的,其次后面的物体颜色也会蒙上一层绿色。这里就涉及到合并阶段颜色合并的一种方式,混合。不再是替换原来的像素的颜色,我们可以配置混合的方式,来决定合并阶段最终像素的输出颜色。
为了避免看到屏幕渲染的过程,屏幕渲染成像不是立即显示在屏幕上的,而是采用了前后缓冲区。首先场景会渲染到后置缓冲区,等渲染完毕,就翻转到前置缓冲区,这时候我们在屏幕上看到了完整的渲染画面。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值