Shader学习基础之一(图形流水线)

时间:2022-05-23 04:46:54

基础篇(一)

图形编程硬件:
历史:图形编程硬件诞生自2003年,简称为GPU编程


支持功能:
1.支持顶点和片段的可编程能力
2.支持IEEE32位的浮点运算(IEEE32是国际电工委员会置顶的浮点书表示方式,主要内容是用四个字节来表示浮点数,可以表示的数据的负数范围是(-2*2)^128~-2^127,2^-127~2*2^128)
3.支持四元向量和四阶矩阵
4.提供分支和循环的控制语句
5.具有高带宽的内存处理能力
6.支持1D,2D,3D的纹理查询和使用能力,而且速度非常块
7.支持绘制到纹理功能


GPU和CUP的关系:
GUP具有高并行的结构,所以在处理图形数据和复杂算法比CUP更加有效率。
Shader学习基础之一(图形流水线)
CPU在执行任务的时候,一个时刻只会处理一个数据,不存在真正意义上的并行,而GPU则有多个处理器核,在一个时刻可以并行处理多个数据。

为什么GPU不能代替CPU?
因为在GPU上我们无法处理数据之间的相关性的算法,简而言之,我们在书写C#程序的时候可以很轻松的处理数据与数据之间的关系,而在Shader上我们则没法实现,因为shader上面的每个属性都是独立的。


GPU图形渲染管线:
图形渲染管线描述GPU的渲染流程:给点视点,三维物体,光源,光照模型和纹理等元素,如何绘制一个2D的图形。
图形渲染管线分为三个阶段:应用程序阶段,几何阶段,光栅阶段


应用程序阶段:
主要使用高级的编程语言进行开发,例如C,C++等
输出:通过数据总线,把几何体的数据(顶点坐标,法向量,纹理坐标,纹理等)传送到图形硬件。


几何阶段:
输入:应用程序末端输出的内容
负责任务:顶点坐标变换,光照,裁剪,投影以及屏幕映射
输出:经过变换和投影之后的屏幕坐标,颜色,以及纹理坐标。

问题:为什么需要对三维空间的顶点进行坐标空间的变换呢?
答:其实输入到计算机当中的是一系列的三维坐标的点,但是我们看到的屏幕是一个二维坐标的点,所以需要转换。

坐标空间类型:ObjectSpace模型空间-WorldSpace世界空间-EyeSpace观察空间-ClipAn’dProjectSpace屏幕空间
Shader学习基础之一(图形流水线)
图中,我们的物体是O,他有一个自己的坐标系,就是物体坐标系(ObjectSpace)。
第一步:我们需要先把物体上的顶点坐标转换到世界坐标系(WorldSpace)中,这个部分我们需要乘一个矩阵,在Unity中这部分我们一般需要左乘矩阵(_object2world),这时我们拿到的顶点坐标就是世界坐标系的物体坐标!

第二步:我们需要把世界空间的坐标转换到我们眼睛所在的坐标系,这样才能共人眼看到,当然,在软件里面,人眼的代表就是摄像机,我们都知道人眼只能看到一个方向,而且太远的地方和太近的地方看不到,那么我们就可以用视角,视线方向,远近裁剪平面来模拟一个视锥体。
Shader学习基础之一(图形流水线)
在这个视锥体之外的所有东西都将要被裁剪,因为程序认为它是不可见的。在这个部分,我们会为每个顶点确定一个深度。

单位立方体:对角顶点分别是(1,1,1)和(-1,-1,-1)也被称为规范立方体(CVV)。
CVV的*面(梯形的较小的平面)对应的是屏幕坐标的xy坐标,z对应的就是深度。
1,我们通常所说的投影就是透视变换矩阵把顶点从视锥体变换到CVV中。
2,在CVV中进行裁剪
3,屏幕映射,讲上边所得到的坐标映射到屏幕坐标系当中
投影:有平行投影和透视


图元装配:
输入:顶点的信息
含义:将顶点根据原始的连接关系,还原出网格结构。
这一阶段会得到很多的小三角形,关于三角形顶点的顺序:我们用右手法则来确定三角形的法向量,如果该向量朝向视点(法向量与到视点的方向点积为正),则这一面是正面,一般顶点按照逆时针排列,一般背面我们是看不到的,就会进行剔除操作,原因是为了减少顶点个数。
裁剪算法:视域剔除,背面剔除,遮挡剔除,视口裁剪
这一过程得到一堆在屏幕坐标系中的三角形面片。


光栅化阶段:
决定哪些像素被几何图元覆盖的过程。
输入数据:屏幕坐标系的顶点值以及我们需要绘制的图元
阶段一:将顶点以及绘制的图元(线,面)对应到相应的像素坐标
阶段二:片段操作,在更新帧缓存之前
a.消除遮挡面
b.纹理操作,根据像素的纹理坐标,查找对应的纹理值
c.混色,根据目前已经画好的颜色与正在计算的颜色透明度,混合两种颜色作为新的颜色输出。
为了在场景中绘制透明物体,通常都需要对物体进行排序,首先绘制不透明物体,然后,在不透明物体的上方,对不透明物体进行由后到前的顺序进行混合处理。
图形过滤器:讲正在计算的颜色通过某种滤镜之后输出
最后将颜色写入帧缓存!


三种语言:
Opengl的GLSL
Dirrect3D的HLSL
NVIDIA的CG

为什么我们的unity中要使用CG语言?
因为CG编写的程序可以同时兼容Opengl和Direct3D两种平台,恰巧我们unity制作需要支持多种平台。

GPU上的两个组件:
可编程顶点处理器可编程片段处理器
顶点和片段着色器拥有强大的并行计算能力,擅长不高于4阶的矩阵运算,片段着色器还支持高速的纹理查询能力。
顶点着色器:
输入:GPU前端模块提取图元信息(顶点位置,法线向量,纹理坐标(uv))等
操作:顶点坐标空间转换,法向量空间转换,光照计算等(现在光照计算一般在片段着色器,比较细),然后将计算好的数据传入指定寄存器中
片段着色器:
输入:顶点着色器传入的数据
操作:光照计算,uv扰动,纹理采样等,最后输出当前片段的颜色给光栅化阶段(片段着色器是对每个独立的颜色进行操作的)
Shader学习基础之一(图形流水线)

片段和像素的区别:所谓片段是所有三位定点在光栅化之后的数据集合,这些数据还没有经过深度值比较,而屏幕显示的像素都是经过深度比较的。