本文共 4711 字,大约阅读时间需要 15 分钟。
查阅过很多资料,在OpenGL的整个渲染流程中很多资料上描述的过程大致相同却又略去了很多细节,可以说是每一份资料的描述都不尽相同,或许每个作者所阐述的重点都不太相同,不存在孰对孰错
例如:《OpenGL ES 3.0编程指南》中对可编程管线的流程介绍如下:
又例如:《实时计算机图形学》一书中,将图形绘制管线分为三个主要阶段:应用程序阶段、几何阶段、光栅阶段
以上,都是关于流程的简要过程,下面会详细的描述整个渲染流程
下面这个图取自《OpenGL ES 3.0编程指南》,此流程为可编程管线。
VBO/VAO(顶点缓冲区对象或顶点数组对象):
VBO/VAO(到底是啥,下回讲解)是cpu提供给GPU的顶点信息,包括了顶点的位置、颜色(只是顶点的颜色,和纹理的颜色无关)、纹理坐标(用于纹理贴图)等顶点信息。VertexShader(顶点着色器):
顶点着色器是处理VBO/VAO提供的顶点信息的程序。VBO/VAO提供的每个顶点都执行一遍顶点着色器。Uniforms(一种变量类型)在每个顶点保持一致,Attribute每个顶点都不同(可以理解为输入顶点属性)。执行一次VertexShader输出一个Varying(可变变量)和gl_positon。顶点着色器的输入包括:
重点:VertexShader就是顶点着色器编程可以操作的阶段,用于控制顶点坐标的转换过程,片段着色器控制着每个像素颜色的计算过程
先说说坐标类型:
Object Space(模型坐标空间) World Space(世界坐标空间) Eye Space(观察坐标空间) Clip and Project Space(屏幕坐标空间)
3.Primitive Assembly(图元装配):
顶点着色器下一个阶段是图元装配,图元(prmitive)是三角形、直线或者点精灵等几何对象。这个阶段,把顶点着色器输出的顶点组合成图元。4.rasterization(光栅化):
光栅化是将图元转化为一组二维片段的过程,然后,这些片段由片段着色器处理(片段着色器的输入)。这些二维片段代表着可在屏幕上绘制的像素。用于从分配给每个图元顶点的顶点着色器输出生成每个片段值的机制称作插值(Interpolation)。这句不是人话的话解释了一个问题,就是从cpu提供的分散的顶点信息是如何变成屏幕上密集的像素的,图元装配后顶点可以理解成变为图形,光栅化时可以根据图形的形状,插值出那个图形区域的像素(纹理坐标v_texCoord、颜色等信息)。注意,此时的像素并不是屏幕上的像素,是不带有颜色的。接下来的片段着色器完成上色的工作。
问题1:如果该图元是点线面中的“点”,那么它的坐标为浮点数,但是像素是由整数来表示的,如何正确计算屏幕坐标所对应的像素?
答: 根据《计算机图形学(第二版)》52页示例:如果一条线段的位置是(10.48,20.51),那么转换到像素的位置则是(10,21)也就是我们说的四舍五入问题2:为什么通过三个点就能自动连接成一个三角形,如果有ABCDEFG….很多个点,如何知道ABC三个点需要组成三角形,而不是用AFG组成三角形?
答:这个问题涉及到划线算法和区域图元填充算法 划线算法有:DDA算法、Bresenham划线算法 区域图元填充算法有:扫描线多边形填充算法、边界填充算法 更多详细的算法内容可以查阅《计算机图形学》第三章
5.FragmentShader(片段着色器):
片段着色器为片段(像素)上的操作实现了通用的可编程方法,光栅化输出的每个片段都执行一遍片段着色器,对光栅化阶段生成每个片段执行这个着色器,生成一个或多个(多重渲染)颜色值作为输出。6.Per-Fragment Operations(逐片段操作)
附上一张中文翻译图,嘿嘿~
(1)pixelOwnershipTest(像素归属测试):
(2)ScissorTest(剪裁测试):
(3)StencilTest and DepthTest(模板和深度测试):
(4)Blending(混合):
(5)dithering(抖动):
最后把产生的片段放到帧缓冲区(前缓冲区或后缓冲区或FBO)中,若不是FBO,则屏幕绘制缓冲区中的片段,产生屏幕上的像素。