赞
踩
VBO/VAO(顶点缓冲区对象或顶点数组对象)
VertexShader(顶点着色器)
rasterization(光栅化)
FragmentShader(片段着色器)
Per-Fragment Operations(逐片段操作)
pixelOwnershipTest(像素归属测试)
ScissorTest(剪裁测试)
StencilTest and DepthTest(模板和深度测试)
Blending(混合)
dithering(抖动)
Frame Buffer (帧缓冲区)
可编程管线渲染流程图1-1:
1、VBO/VAO(顶点缓冲区对象或顶点数组对象):
VBO/VAO(到底是啥,下回讲解)是cpu提供给GPU的顶点信息,包括了顶点的位置、颜色(只是顶点的颜色,和纹理的颜色无关)、纹理坐标(用于纹理贴图)等顶点信息。
2、VertexShader(顶点着色器):
顶点着色器是处理VBO/VAO提供的顶点信息的程序。VBO/VAO提供的每个顶点都执行一遍顶点着色器。Uniforms(一种变量类型)在每个顶点保持一致,Attribute每个顶点都不同(可以理解为输入顶点属性)。执行一次VertexShader输出一个Varying(可变变量)和gl_positon。
顶点着色器的输入包括:
着色器程序:描述顶点上执行操作的顶点着色器程序源代码或者可执行文件
顶点着色器输入(或者属性):用顶点数组提供的每个顶点的数据
统一变量(uniform):顶点/片段 着色器使用的不变数据
采样器(Samplers):代表顶点着色器使用纹理的特殊统一变量类型
戏中通常摄像机就是eye space
eye space概念:视点(camera、相机、眼睛)为原点,由视线的方向、视角范围、远近平面,组成一个梯形的三维空间,我们称之为 viewing frustum(视锥)
超出这个梯形范围的物体将会被剔除,也就是说我们看不见,这项技术被称之为Furstum Culling(视锥剪裁)
Eye Space到Clip and Project Space
在视锥体中(那个不规则的梯形)进行剪裁并非易事,所以图形学前辈们精心分析之后,剪裁被安排到一个单位立方体中进行,该立方体的对角顶点分别是(-1,-1,-1)和(1,1,1),称之为规范立方体(简称CVV:Canonical view volume),CVV的近平面(梯形较小的矩形面)对应的屏幕像素坐标是(左下角的0,0)
1.把视锥体变换到CVV中,这个过程就是“投影”,投影的方法有2种:正投影(平行投影)和透视投影,一般在游戏里都有这两种类型的摄像机,正投影就好像一个无限延伸的长方体,透视投影就好像是一个梯形
2.确定只有图元完全或者一部分在视锥体内部的时候,才需要进行光栅化
如果图元完全在视锥体内部:该图元直接进入下一个阶段
如果图元部分在视锥体内部:进行剪裁处理,详细的剪裁算法大家自行查阅一下《计算机图形学》第12章第5节
如果图元完全不在视锥体内部:直接剔除
3.Primitive Assembly(图元装配):
顶点着色器下一个阶段是图元装配,图元(prmitive)是三角形、直线或者点精灵等几何对象。这个阶段,把顶点着色器输出的顶点组合成图元。
将顶点数据根据Primitive(原始链接关系)还原出网格结构,网格由顶点和索引组成,在此阶段根据索引将顶点链接在一起,组成点、线、面三种不同的图元,之后就是对超出屏幕的三角形进行剪裁,如果三角形ABC三个顶点其中一个点在屏幕的外面,另外两个点在屏幕里面,其实屏幕上看到的应该是个四边形,然后再将这个四边形切成2个小的三角形
简而言之,将顶点着色器计算之后得到的点根据链接关系组成点、线、面(三角形)
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(逐片段操作)
* 在该阶段,每个片段都会执行下面的5个操作
(1).pixelOwnershipTest(像素归属测试):
这个用来确定帧缓冲区中位置(x,y)的像素是不是归当前上下文所有。例如,如果一个显示帧缓冲区窗口被另一个窗口所遮蔽,则窗口系统可以确定被遮蔽的像素不属于此opengl的上下文,从而不显示这些像素。
(2).ScissorTest(剪裁测试):
如果该片段位于剪裁区域外,则被抛弃
(3).StencilTest and DepthTest(模板和深度测试):
深度测试比较好理解,若片段着色器返回的深度小于缓冲区中的深度,则舍弃。模板测试没有用过,不清楚具体功能,猜测功能应该和名字一样,模板形状内可通过。
(4).Blending(混合):
将新生成的片段颜色值与保存在帧缓冲区的颜色值组合起来,产生新的RGBA。
(5).dithering(抖动):
在逐片段操作阶段的最后,片段要么被拒绝,要么在帧缓冲区(x,y)的某个位置写入片段的颜色,深度或者模板值。写入片段颜色,深度和模板值取决于弃用的相应写入掩码。写入掩码可以更精确的控制写入相关缓冲区的颜色、深度和模板值。例如:可以设置颜色缓冲区的写入掩码,使得任何红色值都不能被写入颜色缓冲区。
最后把产生的片段放到帧缓冲区(前缓冲区或后缓冲区或FBO)中,若不是FBO,则屏幕绘制缓冲区中的片段,产生屏幕上的像素。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。