转载请注明出处:http://www.cnblogs.com/Ray1024

一、概述

这篇文章主要讲解渲染管线(rendering pipeline)的理论知识。

渲染管线是指:在给定一个3D场景的几何描述及一架已确定位置和方向的虚拟摄像机(virtual camera)时,根据虚拟摄像机的视角生成2D图像的一系列步骤。

下图所示为构成渲染管线的各个阶段,以及与各个阶段相关的内存资源。

从上图中我们可以看到,渲染管线就像工厂中的流水线,把各个处理过程分成不同的阶段,各个阶段可以独立工作,这样,各个阶段就可以同时工作,效率自然就会比较高。3D渲染从最初的场景描述到最终的显示结果,这整个过程就是在3D渲染管线中完成的。

这篇文章中,我们将详细讲解D3D11中渲染管线的各个阶段。

二、渲染管线的各个阶段

2.1 输入装配阶段

输入装配(Input Assembler,简称IA)阶段从内存读取几何数据(顶点和索引)并将这些数据组合为几何图元(例如,三角形、直线)。我们通过指定图元拓扑来告诉Direct3D以何种方式组成几何图元。D3D11中常见的拓扑类型有以下几种:

(1)点列表(point list):每个顶点都会被绘制为一个独立的点,如下图:

(2)线带(line strip):前后相邻的两个顶点会形成一条直线,如下图:

(3)线列表(line list):每两个顶点会形成一条独立的直线,如下图:

(4)三角形带(triangle strip):带状方式形成连续的三角形,如下图:

(5)三角形列表(triangle list):每三个顶点会形成一个独立的三角形,如下图:

例如,使用三角形列表来构建四边形,给出顶点数组和索引列表:

Vertex v[4] = {v0, v1, v2, v3};

UINT indexList[6] = {0, 1, 2,   // Triangle0

  0, 2, 3};  // Triangle1

构成下图由两个三角形组成的四边形:

除了这5种拓扑图元类型外,还有两种:带有邻接信息的图元和控制点面片列表。这里不多作介绍,在后面学习到曲面细分技术时再来了解。

2.2 顶点着色器阶段

在完成图元装配后,顶点将被送往顶点着色器(vertex shader)阶段。

顶点着色器可以被看成是一个以顶点作为输入输出数据的函数。每个将要绘制的顶点都会通过顶点着色器推送至硬件。顶点着色器函数由我们自己编写,但是它会在GPU上运行,所以执行速度非常快。许多效果,比如变换(transformation)、光照(lighting)和置换贴图映射(displacement mapping)都是由顶点着色器来实现的。记住,在顶点着色器中,我们不仅可以访问输入的顶点数据,也可以访问在内存中的纹理和其他数据,比如变换矩阵和场景灯光。

(1) 局部空间和世界空间

我们在创建3D场景时,不在全局场景坐标系(world space,世界空间)中建立物体,而是在局部坐标系(local space,局部空间)中建立物体;局部坐标系是最常用的实用坐标系,它的原点接近于物体中心,坐标轴的方向与物体的方向对齐。在完成3D模型的制作之后,将模型放到全局场景中;通过计算局部坐标系相对于世界坐标系的原点和轴向,实现相应的坐标转换变换。将坐标从局部坐标系转换到世界坐标系的过程称为世界变换(world transform),相应的变换矩阵称为世界矩阵(world matrix)。当所有的物体都从局部空间变换到世界空间后,这些物体就会位于同一个坐标系(世界空间)中。如果你希望直接在世界空间中定义物体,那么可以使用单位世界矩阵(identity world matrix)。

(2)观察空间

我们在场景中指定一个虚拟摄像机,我们把一个局部坐标系(称为观察空间、视觉空间或摄像机空间)附加在摄像机上,该坐标系以摄像机的位置为原点,以摄像机的观察方向为z轴正方向,以摄像机的右侧为x轴,以摄像机的上方为y轴。在渲染管线的随后阶段中,使用观察空间来描述顶点比使用世界空间来描述顶点要方便的多。从世界空间到观察空间的坐标转换称为观察变换(view transform),相应的矩阵称为观察矩阵(view matrix)。

(3)投影与齐次剪裁空间

摄像机能看到的范围通过一个平截头体(frustum)来描述,它是一个在近平面处削去尖部的棱锥体,如下图。

这个空间即世界空间的物体被投影到相应的投影面上之后,继而进行裁剪操作所在的空间叫投影与齐次剪裁空间。

2.3 曲面细分阶段

Hull Shader Stage、Tessellation Stage、Domain Shader Stage统称为曲面细分阶段(Tessellation Stage),指通过添加三角形的方式对一个网格的三角形进行细分,这些新添加的三角形可以偏移到一个新的位置,让网格的细节更加丰富。曲面细分阶段是Direct3D 11中新添加的,这样我们就可以在GPU上对几何体进行细分了。曲面细分阶段是可选的,我们将在以后详细介绍。

2.4 几何着色器阶段

几何着色器阶段(geometry shader stage)是D3D11中加入的新特性,是可选的。几何着色器以完整的图元作为输入数据。例如,当我们绘制三角形列表时,输入到几何着色器的数据是构成三角形的三个点。(注意,这三个点是从顶点着色器传递过来的。)几何着色器的主要优势是它可以创建或销毁几何体。例如,输入图元可以被扩展为一个或多个其他图元,或者几何着色器可以根据某些条件拒绝输出某些图元。这一点与顶点着色器有明显的不同:顶点着色器无法创建顶点,只要输入一个顶点,那么就必须输出一个顶点。几何着色器通常用于将一个点扩展为一个四边形,或者将一条线扩展为一个四边形。这是一项高级技术,我们会在后面的章节中对它进行讨论,这里只做一个简短的概述。

2.5 光栅化阶段

光栅化(rasterization)阶段的主要任务是为投影后的3D三角形计算像素颜色。这个阶段属于不可编程阶段,即完全由硬件实现,主要包括:

(1)视口变换

即把投影变换后得到的顶点的x,y坐标,根据用户设定的视口参数,变换到屏幕上对应的坐标。

(2)背面消隐(Backface Culling)

摄像机不会看到实心物体的背面,所以绘制它们是毫无意义的。背面消隐是指让管线放弃对朝后的三角形的处理。这可以将所要处理的三角形的数量降低到原数量的一半。

(3)顶点属性差值

我们通过指定三角形的3个顶点来定义一个三角形。除位置外,顶点还可以包含其他属性,比如颜色、法线向量和纹理坐标。在视口变换之后,这些属性必须为三角形表面上的每个像素进行插值。顶点深度值也必须进行插值,以使每个像素都有一个可用于深度缓存算法的深度值。对屏幕空间中的顶点属性进行插值,其实就是对3D空间中的三角形表面进行线性插值这一工作需要借助所谓的透视矫正插值(perspective correct interpolation)来实现。本质上,三角形表面内部的像素颜色都是通过顶点插值得到的。

2.6 像素着色器阶段

像素着色器(Pixel shader)是由我们编写的在GPU上执行的程序。像素着色器会处理每个像素片段(pixel fragment),它的输入是插值后的顶点属性,由此计算出一个颜色。像素着色器可以非常简单地输出一个颜色,也可以很复杂,例如实现逐像素光照、反射和阴影等效果。

2.7 输出合并阶段

在输出合并(output merger,简称OM)阶段中,某些像素片段会被丢弃(例如,未能通过深度测试或模板测试)。未丢弃的像素片段会被写入后台缓冲区。混合(blending)工作是在该阶段中完成的,一个像素可以与后台缓冲区中的当前像素进行混合,并以混合后的值作为该像素的最终颜色。某些特殊效果,比如透明度,就是通过混合来实现的,我们在以后的学习中会介绍。

三、结语

Direct3D11整个渲染管线就介绍到这里,我们最后总结一下,渲染管线的各个阶段按照先后顺序分别为:输入装配阶段、顶点着色器阶段、曲面细分阶段、几何着色器阶段、光栅化阶段、像素着色器阶段和输出合并阶段。

3D渲染管线是非常重要的3D图形学的理论知识。在之后的学习中,我们将学习渲染管线的实际使用。

Direct3D11学习:(六)渲染管线的更多相关文章

  1. Direct3D11学习:(八)Effects介绍

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 Effects框架是一组用于管理着色器程序和渲染状态的工具代码.例如,你可能会使用不同的effect绘制水.云. ...

  2. Direct3D11学习:(七)绘图基础——彩色立方体的绘制

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 在前面的几篇文章中,我们详细介绍了Direct3D渲染所需要的数学基础和渲染管道理论知识.从这篇文章开始,我们就 ...

  3. Direct3D11学习:(五)演示程序框架

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 在此系列最开始的文章Direct3D11学习:(一)开发环境配置中,我们运行了一个例子BoxDemo,看过这个例 ...

  4. Hbase深入学习(六) Java操作HBase

    Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...

  5. TweenMax动画库学习(六)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  6. SVG 学习<六> SVG的transform

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  7. C#多线程学习(六) 互斥对象

    如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先 ...

  8. Unity学习(六)5.x依赖打包

    http://blog.sina.com.cn/s/blog_89d90b7c0102w2ox.html unity5已经封装好了接口,所以依赖打包并没有那么神秘和复杂了. 打包: 1.定义好资源的a ...

  9. (转)MyBatis框架的学习(六)——MyBatis整合Spring

    http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...

  10. cesium 学习(六) 坐标转换

    cesium 学习(六) 坐标转换 一.前言 在场景中,不管是二维还好还是三维也罢,只要涉及到空间概念都会提到坐标,坐标是让我们理解位置的一个非常有效的东西.有了坐标,我们能很快的确定位置相关关系,但 ...

随机推荐

  1. ASSIC码对照表

    编码对应字符: ✔:\u2714✘:\u2718 <script type="text/javascript"> var aaa = "\u2718" ...

  2. linux下的依赖关系

    1.一般来说依赖关系可以使得软件较小并且某个lib修复bug以后所有被依赖的软件都能得到好处. 依赖关系下,对于维护也有利有弊,第一,若某个被依赖的软件出现bug或者漏洞,这时候就只需要维护一个软件, ...

  3. ELK——Logstash 2.2 mutate 插件【翻译+实践】

    官网地址 本文内容 语法 测试数据 可选配置项 mutate 插件可以在字段上执行变换,包括重命名.删除.替换和修改.这个插件相当常用. 比如: 你已经根据 Grok 表达式将 Tomcat 日志的内 ...

  4. 七牛CEO许式伟:移动游戏资源存贮的大趋势

    (国内知名Android开发论坛eoe开发者社区推荐:http://www.eoeandroid.com/) 9月14日,eoe移动开发者大会正式在北京国家会议中心召开,七牛云储存CEO许式伟先生做了 ...

  5. 软件包管理 之 RPM 基础 《RPM 的介绍和应用》

    RPM 是 Red Hat Package Manager 的缩写,本意是Red Hat 软件包管理,顾名思义是Red Hat 贡献出来的软件包管理:在Fedora .Redhat.Mandriva. ...

  6. [转]Android 超高仿微信图片选择器 图片该这么加载

    快速加载本地图片缩略图的方法: 原文地址:Android 超高仿微信图片选择器 图片该这么加载 其示例代码下载: 仿微信图片选择器 ImageLoader

  7. 【转】安装OpenSSL缺失Microsoft Visual C++ 2008 Redistributables的解决方案

    from: http://www.cnblogs.com/luguo3000/p/3539815.html 在安装OpenSSL的时候通常会提示以下错误: "The Win32 OpenSS ...

  8. HL AsySocket 服务开发框架 - 业务逻辑层

    一 概述 Socket服务只是提供一个网络传输服务. 业务逻辑层在整体架构中的位置在那里呢,如图: 网络层将解包后的消息包抛至业务逻辑层,业务逻辑层收到消息包后,解析消息类型,然后转入相应的处理流程处 ...

  9. The model backing the <Database> context has changed since the database was created.

    Just found out the answer and thought of updating here. Just need to do the following. public class ...

  10. C# 用代码创建 DataSet 和 DataTable 的列和记录

    System.Data.DataSet objSet = new DataSet(); System.Data.DataTable objTable = new DataTable("tes ...