第2章 渲染流水线

来源:互联网 发布:上海淘宝厂家 编辑:程序博客网 时间:2024/04/29 22:13

    渲染流水线的最终目的在于生成或者说死渲染一张二维纹理

2.1 综述

    Shader是渲染流水线中的一个环节(硬件把流水线中的部分控制权放给用户,开发者通过Shader控制部分流水线上的工作)

2.1.1 什么是流水线

    流水线将一个任务拆分为多个步骤,并通过多个单元并行处理,使得各个单元专注于自身的工作,简化单元设计。单个任务,所使用的时间为所有单元处理时间之和,
但在整体上,总任务时间为: 任务数量*最耗时的步骤耗费时间 / 流水线数量,所以通过细分流水线(需要增加处理单元),增加流水线,可以提高效率,同时,减少最耗时的步骤耗费时间(瓶颈),也可以提高效率,理论上,如果每个步骤耗时相等,可以达到最优(不需要等待)
    流水线增加效率的前提是增加处理单元,并且拆分的各个步骤可以并行

2.1.2 什么是渲染流水线

    渲染流水线的任务是由一个三维场景触发,生成(或者说渲染)一张二维图像,换句话说,计算机需要从一系列的顶点数据,纹理等信息触发,把这些信息最终转换成一张人眼可以看到的图像,这个工作通常由CPU和GPU共同完成(如果使用软件渲染器,则不需要GPU)。
    《Real-Time Rendering,Third Edition》一书中将一个渲染流程分成3个阶段: 应用阶段(Application Stage)、几何阶段(Geometry State)、光栅化阶段(Rasterizer State)。每个阶段本身通常也是一个流水线,应用阶段通常由CPU完成,几何阶段和光栅化阶段通常由GPU完成。

    应用阶段: 

        由CPU负责实现,开发者具有绝对控制权。
        这一阶段中,开发者有3个主要任务: 首先,需要准备好场景数据,其次,粗粒度剔除,把那些不可见物体剔除出去,最后,设置渲染状态
        这一阶段最终输出几何图元信息,并传递给几何阶段

    几何阶段:

        一般由GPU负责实现(软件渲染器除外)
        处理所有和我们要绘制的几何相关的事情。例如,决定需要绘制的图元是什么,怎样绘制他们,在哪里绘制他们。
        进行逐顶点,逐多边形的操作。一个重要任务就是把顶点坐标变换到屏幕空间,再交给光栅器处理

    光栅化阶段:

        一般由GPU负责实现(软件渲染器除外)
        主要决定每个渲染图元中的像素应该绘制到屏幕
        以上一个阶段输出的顶点信息作为输入,通过插值,进行逐像素处理

2.2 CPU和GPU之间的通信

    渲染流水线起点是CPU,即应用阶段。
        (1) 把数据加载到显存
        (2) 设置渲染状态
        (4) 调用Draw Call (个人见解:应该是提交渲染指令)

2.2.1 把数据加载到显存中

    所有渲染所需的数据都需要从硬盘中加载到系统内存(个人见解: 有些数据可以从GPU回读),然后网格和纹理数据又被加载到显存。因为显卡访问显存速度更快,而且大多数显卡对于RAM没有直接的范围权利(有些设备显存是从RAM中划出一块区域的)

2.2.2 设置渲染状态

    渲染状态定义了场景中的网格是怎么被渲染。例如,使用哪个顶点着色器(Vertex Shader)/片元着色器(Fragment Shader),光源属性,材质等。
    如果没有更改渲染状态,那么后面的网格也会使用之前网格使用的渲染状态

2.2.3 调用 Draw Call

    Draw Call就是一个命令,由CPU发起,接收方是GPU,这个命令仅仅会指向一个需要被渲染的图元列表而不会再包含任何材质信息
    当给定一个Draw Call GPU就会根据渲染状态(例如材质,纹理,着色器等)和所有输入的顶点数据进行计算,最终输出成屏幕上显示的那些像素

2.3 GPU流水线

    当GPU从CPU那里得到渲染命令后,就会进行一系列流水操作,最终把图元渲染到屏幕上

2.3.1 概述

    在几何阶段和光栅化阶段,通常由GPU实现(软件渲染器除外),开发者无法拥有绝对控制权,但GPU向开发者开放了很多控制权。两个阶段可以分成若干更小的流水线阶段,每个小阶段提供了不同的可配置性或可编程性。
    几何阶段,以应用阶段输出的顶点信息作为输入,并输出屏幕空间的图元顶点信息,这些图元顶点信息携带了位置,深度,纹理坐标等信息
    光栅化阶段,以几何阶段输出的顶点信息作为输入,输出最终的像素信息

    顶点着色器(Vertex Shader): 完全可编程,必须实现,通常用于实现顶点的空间变换,顶点着色等功能。
    曲面细分着色器(Tessellation Shader): 可选,用于细分图元,比如对某些曲面增加图元信息,增加细节(不懂)
    几何着色器(Geometry Shader): 可选,用于逐图元着色,或者用于产生更多图元,或者剔除图元
    裁剪(Clipping): 可配置,用于将不在摄像机视野内的顶点裁剪掉,并剔除某些三角图元的面片(比如背面剔除) 
    屏幕映射(Screen Mapping): 不可配置不可编程,用于把每个图元的坐标映射到屏幕坐标系中
    
    三角形设置 (Triangle Setup): 不可配置不可编程, 将上一个阶段输出的顶点信息整合成三角形输出
三角形遍历(Triangle Traversal): 不可配置不可编程,检测被三角形覆盖的像素,并生成片元
逐片元操作(Fragment Shader): 可编程,用于逐片元操作,输出最终像素

2.3.2 顶点着色器

    顶点着色器处理CPU传来的顶点数据,进行坐标变换和顶点光照。无法创建或销毁任何顶点,也无法获得顶点与顶点间的关系。
    最少要进行一次坐标变换,顶点从模型空间转换到齐次裁剪空间(个人),并做透视除法,进行归一化。
    (进行了一次投影矩阵的计算,可以确定一个点是否在裁剪空间)

2.3.3 裁剪

    对部分在视野内的图元进行处理,只保留在视野内的部分,可能会增加顶点

2.3.4 屏幕映射

    把上一阶段的顶点信息映射到屏幕空间
    OpenGL左下角为(0,0)点,DirectX左上角为(0,0)点
原创粉丝点击