Unity Shader 之 渲染流水线

  Shader既着色器,与其相关的就是渲染流水线,Shader不过是其中得可编程部分。

渲染流水线

  分为3个阶段:应用阶段、几何阶段、光栅化阶段。

应用阶段

  由CPU负责实现,开发者有这个阶段的绝对控制权。这个阶段最重要的作用是输出渲染所需的几何信息,即渲染图元(点、线、三角面等)。

几何阶段

  处理所有和我们要绘制的几何相关的事情。这个阶段的重要作用是把顶点坐标变换到屏幕空间中,再交给光栅器进行处理。将会输出屏幕坐标的二维顶点坐标、每个顶点对应的深度值、着色等相关信息。

  分为:顶点着色器、曲面细分着色器、几何着色器、裁剪、屏幕映射。

  顶点着色器

    输入:CPU

    处理:顶点

    主要工作:坐标变换和逐顶点光照

    坐标变换:把顶点坐标从模型空间转换到齐次剪裁空间。最终得到归一化的设备坐标(NDC)。注:OpenGL的NDC的z分量范围在[-1,1],DirectX中,NDC的z分量范围是[0,1]

  裁剪

    目的:不在摄像机范围内的物体不需要被处理

    图元与摄像机视野的关系:完全在视野内、部分在视野内、完全在视野外。

      完全在视野内:保留

      完全在视野外:裁剪

      部分在视野内:视野外的顶点用新的顶点来代替,新的顶点位于这条线段和视野边界的交点处。

  屏幕映射

    任务:将每个图元的x和y坐标转换到屏幕坐标系下

    原z坐标:屏幕坐标系和z坐标系一起构成了一个坐标系,叫窗口坐标系

    屏幕坐标系:OpenGL把屏幕的左下角当成最小的窗口坐标值,而DirectX则为屏幕左上角。

光栅化阶段

  使用上一阶段的数据来产生屏幕上的像素,并最终渲染出最终的图像。GPU上运行

  分为:三角形设置、三角形遍历、片元着色器、逐片元操作

  三角形设置

    目标:计算每个图元覆盖了哪些像素,以及为这项像素计算他们的颜色。

  三角形遍历

    作用:检查每个像素是否被一个三角网络所覆盖。如果覆盖的话,就生成一个片元,也成为扫描变换。

    使用三角形网络3个顶点的顶点信息对整个覆盖区域的像素进行差值。

    结果:得到一个片元序列。

  片元着色器(像素着色器DirectX)

    输入:顶点着色器中顶点信息差值得到的结果。

    输出:一个或多个颜色值。

    作用:纹理采样(在顶点着色器中输出每个顶点对应的纹理坐标,然后进行差值得到纹理坐标)

  逐片元操作(输出合并阶段DirectX)

    任务:1.决定每个片元的可见性(深度测试、模板测试等)

       2.通过了测试后,片元的颜色值和已经存储在颜色缓冲区的颜色进行合并,或者混合。

    片元 —> 模板测试 —> 深度测试 —> 混合 —> 颜色缓冲区

    深度测试一般用于剔除太远的不可见片元,或者帮助剔除被遮挡的片元。

    Blend(混合),开启后会把当前计算的颜色与颜色缓冲区里的颜色进行混合(透明物体),关闭后则会直接覆盖(非透明物体)。

最后几个问题

  什么是 Draw Call ?

  答:Draw Call本身的含义是CPU调用图像编程接口。

  CPU 和 GPU是如何实现并行工作的 ?

  答:命令缓冲区,由CPU向其中添加命令,GUP从中取命令,添加与读取相互独立(队列),Draw Call只是其中一种命令。

  为什么 Draw Call 多了会影响帧率 ?

  答:每次调用Draw Call之前,CPU需要发送很多内容给GPU,如数据、状态、和命令等。所以CPU需要做很多工作,如检查渲染状态等。而GPU渲染能力强,渲染200和渲染2000个三角形网格通常没有什么区别,所以GPU的处理速度就会快过CPU提交命令的速度。如果Draw Call过多,CPU会把大量时间花费在提交Draw Call上,造成CPU过载。

原文地址:https://www.cnblogs.com/SHOR/p/7819541.html