1.顶点着色器

顶点着色器是流水线的第一个阶段,它的输入来自于CPU。顶点着色器的处理单位是顶点,也就是说输入进来的每个顶点都会调用一次顶点着色器。

顶点着色器需要完成的工作主要有:坐标变换和逐顶点光照。当然,除了这两个主要任务外,顶点着色器还可以输出后续阶段所需的数据。

坐标变换,顾名思义,就是对顶点的坐标进行某种变换。例如我们可以通过改变顶点位置来模拟水面,布料等。

一个最基本的顶点着色器必须完成的一个工作是:把顶点坐标从模型空间转换到齐次剪裁空间。类似下面代码:

o.pos=mul(UNITY_MVP,v.position);

2.裁剪

由于我们的场景可能会很大,而摄像机的视野范围很有可能不会覆盖所有的场景物体,一个很自然的想法就是,那些不在摄像机视野范围内的物体不需要被处理,而裁剪就是为了完成这个目的而被提出来的。

一个图元和摄像机的关系有3种:

  • 完全在视野内
  • 部分在视野内
  • 完全在视野外

    部分在视野内的图元需要裁剪,例如一条线段的一个顶点在视野内,而另一个顶点在视野外,那么视野外部的顶点应该使用一个新的顶点来代替,这个新的顶点位于这条线段和视野边界的交点处。

3.屏幕映射

这一步输入的坐标仍然是三维坐标系。屏幕映射的任务是把每个图元的x和y坐标转换到屏幕坐标系下,屏幕坐标系是一个二维坐标系,它和我们用于显示画面的分辨率有很大关系。

屏幕映射得到的屏幕坐标决定了这个顶点对应屏幕上哪个像素以及距离这个像素有多远。

opengl的屏幕坐标原点是左下角,而directx是左上角,如果你发现你得到的图像是倒转的,那么很有可能就是这个原因造成的。

4.三角形设置

由这一步就进入了光栅化阶段,从上一个阶段输出的信息是屏幕坐标下的顶点位置以及和它们相关的额外信息,如深度值、法线方向、视角方向等,光栅化有两个最重要的目标:计算每个图元覆盖了哪些像素,以及为这些像素计算他们的颜色。光栅化的第一个流水线阶段是三角形设置,这个阶段会计算光栅化一个三角网格所需的信息。

具体来说,上一个阶段输出的都是三角网格的顶点,即我们得到的是三角网格每条边的两个端点。但如果要得到整个三角网格对像素的覆盖情况,我们就必须计算每条边上的像素坐标。为了能够计算边界像素的坐标信息,我们就需要得到三角形边界的表示方式。这样一个计算三角形网格表示数据的过程就叫做三角形设置,它的输出是为了下一个阶段做准备。

5.三角形遍历

三角形遍历阶段将会检查每个像素是否被一个三角形网格所覆盖。如果被覆盖的话,就会生成一个片元,而这样一个找到哪些像素被三角网格覆盖的过程就是三角形遍历,这个阶段也被称为扫描变换。

三角形遍历阶段会根据上一个阶段的计算结果来判断一个三角网格覆盖了哪些像素,并使用三角网格3个顶点的顶点信息对整个覆盖区域的像素进行插值。

6.片元着色器

片元着色器是另一个非常重要的可编程着色器阶段,片元着色器的输入是上一个阶段对顶点信息插值得到的结果,更具体来说,是根据那些从顶点着色器输出的数据插值得到的。而它的输出是一个或多个颜色值。

这一阶段可以完成很多重要的的渲染技术,其中最重要的技术之一就是纹理采样。为了在片元着色器中进行纹理采样,我们通常会在顶点着色器阶段输出每个顶点对应的纹理坐标,然和经过光栅化阶段对三角网格的3个顶点对应的纹理坐标进行插值后,就可以得到其覆盖的片元的纹理坐标了。

7.逐片元操作

逐片元操作是opengl中的说法,在directx中,这一阶段被称为输出合并阶段。

这一阶段有几个主要任务:

  • 决定片元的可见性。涉及很多测试工作,如深度测试,模版测试等。
  • 如果一个片元通过了所有的测试,就需要把这个片元的颜色值和已经存储在颜色缓冲区中的颜色进行合并

至此,整个GPU渲染管线就结束了。

GPU渲染管线概述的更多相关文章

  1. OpenGL实现通用GPU计算概述

    可能比較早一点做GPU计算的开发者会对OpenGL做通用GPU计算,随着GPU计算技术的兴起,越来越多的技术出现,比方OpenCL.CUDA.OpenAcc等,这些都是专门用来做并行计算的标准或者说接 ...

  2. GPU渲染管线与shader

    1 几何阶段(顶点shader处理这部分) 模型坐标空间-世界坐标空间-观察坐标空间-屏幕坐标空间 其中从观察空间 到 屏幕空间需要经过3步(CVV单位立方体,规范立方体) a用透视变换矩阵把顶点从视 ...

  3. 【Aladdin Unity3D Shader编程】之一 基本入门

    OpenGL.DirectX以及GLSL.HLSL.CG OpenGL和DirectX是图像应用编程接口,用于渲染二维或者三维图形. GLSL着色语言是用来在OpenGL中着色编程的语言,有点在于跨平 ...

  4. 深入GPU硬件架构及运行机制

    目录 一.导言 1.1 为何要了解GPU? 1.2 内容要点 1.3 带着问题阅读 二.GPU概述 2.1 GPU是什么? 2.2 GPU历史 2.2.1 NV GPU发展史 2.2.2 NV GPU ...

  5. 小强学渲染之OpenGL渲染管线详析

    什么是OpenGL? OpenGL是一套图形硬件的软件API接口库,它直接和GPU交互,将3D场景渲染绘制到2D屏幕上.总结说,OpenGL的功能是将程序中定义的各种2D或3D模型绘制到帧缓存中,或者 ...

  6. GPU寄存器相关

    1,shader model 3.0 只有256个常量寄存器,32个临时寄存器.对应dx9, opengl2.0, opengles2.0 2,shader model 4.0 有65536个寄存器, ...

  7. [转]3D渲染管线

    转自:http://tgerm.org/SRP/ 在3D中有两种渲染管线,分别是图形渲染管线和GPU渲染管线. 图形渲染管线 <Render-Time Rendering Third Editi ...

  8. 【CUDA 基础】3.1 CUDA执行模型概述

    title: [CUDA 基础]3.1 CUDA执行模型概述 categories: CUDA Freshman tags: CUDA SM SIMT SIMD Fermi Kepler toc: t ...

  9. cg语言学习&&阳春白雪GPU编程入门学习

    虽然所知甚少,但康大的<GPU编程与Cg编程之阳春白雪下里巴人>确实带我入了shader的门,在里面我第一次清晰地知道了“语义”的意思,非常感谢. 入门shader,我觉得可以先读3本书: ...

随机推荐

  1. PHP连接和拆分数组array_combine()和array_slice()用法示例

    一提起数组,可能很多PHP初学者会觉得难,但开发一些高级应用的时候,又离不开数组的使用.下面就来说下,PHP使用array_combine()函数来连接数组.用array_slice()函数来拆分数组 ...

  2. 使用jquery时一些小技巧的总结

    使用 each 遍历 var nodes = Ztree.getCheckedNodes(true); //获取所有勾选的节点 $.each(nodes,function(i,value){ aler ...

  3. js原生继承之——构造函数式继承实例

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  4. MySQL生产库全库备份脚本

    创建一个单独的备份用户backup,不要用root 创建备份目录 :mkdir -p /databackup/fullbackup mysql> grant SELECT,RELOAD,SHOW ...

  5. 深入理解HTTP协议(转)

    http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web C ...

  6. leetcode[170]Two Sum III - Data structure design

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  7. C++编程之面向对象的三个基本特征

    面向对象的三个基本特征是:封装.继承.多态. 封装 封装最好理解了.封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类 ...

  8. 如何在NodeJS项目中优雅的使用ES6

    如何在NodeJS项目中优雅的使用ES6 NodeJs最近的版本都开始支持ES6(ES2015)的新特性了,设置已经支持了async/await这样的更高级的特性.只是在使用的时候需要在node后面加 ...

  9. php扩展SeasLog应用于 yii2 组件

    一.seaslog 简单介绍及使用原因 它是C 写的PHP扩展,性能很高,使用简单,能满足大部分简单的日志需求.(个人感觉) 其他优势请看-->https://github.com/Neeke/ ...

  10. Express与NodeJs创建服务器的两种方法

    NodeJs创建Web服务器 var http = require('http'); var server = http.createServer(function(req, res) { res.w ...