Skip to content

Latest commit

 

History

History
78 lines (42 loc) · 5.08 KB

022-modern-gpu-3.md

File metadata and controls

78 lines (42 loc) · 5.08 KB

022. 现代显卡之三

本来想这一节主要写一个固定管线与可编程管线的区别。

知乎上大能很多,这个回答里面的图拿过来用一下: 可编程渲染管线比固定管线的优势在哪?有什么应用? - 王天祺的回答 - 知乎 https://www.zhihu.com/question/28024422/answer/39097192

渲染管线要做的事情就是下面这张图上展示的事情,即把一个3D的场景转换成一个2D的图片。

要完成这件事情,需要几个步骤:

项点着色器

1. 坐标转换

一个场景里一般都有多个3D物体,这些3D物体在设计的时候是不可能考虑它在场景里的位置的,因为它的场景里的位置可能随着时间变化而变化。所以设计一个3D物体的时候,使用的坐标系一般是以物体的中心点为坐标原点。

设计3D物体的时候也不可能考虑屏幕的大小的,更不用提物体还可能被放大缩小,所以物体的坐标范围通常不是01080这样的整数值,而是0.01.0这样归一化的浮点数。

要把一个物体放在场景里显示的时候,首先要确定这个物体在放场景里哪个位置,然后相应的每一个顶点都要根据一个变化矩阵变化成场景里的坐标,也叫世界坐标系坐标。

场景里的景物是要给摄像机看,为了方便摄像机拍摄,还要将场景里的每个物体的坐标转换为摄像机为原点的坐标。摄像机坐标与世界坐标的对应关系也并非一成不变的,因为在一个游戏里,摄像机是可以被玩家操控去看世界的不同位置的。

2. 光照

一个模形是由网格组成的,网络是由一组顶点和一组顶点间的连线关系来确定的,模型中一个顶点不光有坐标信息,还要有这个顶点的颜色信息(颜色可以是rgba颜色,也可以通过纹理坐标间接指定一张贴图上某个坐标位置上的颜色)。网格面上的颜色要由顶点的颜色插值获得。所以要想渲染出一个有颜色的物体,就要先渲染这个物体模型上的每一个顶点。顶点除了有固定的颜色之外,还有法线信息,法线指定了这个顶点在受到光照时反射光的方向。这个也很重要,如果光线反射的方向不对着摄像机,在摄像机看来这个点可能就是一个非常暗,甚至是黑色的。

光照除了光源直射还包括散射、自发光等情形,具体可以参考一下: https://blog.csdn.net/xuexiaokkk/article/details/49513463

以上两个操作都需要对每个顶点操作,并且有一定的模式可循。硬件上会实现为一个称为顶点着色器的东西。

在固定管线GPU中,顶点着色器可以执行的操作是有限的,可以通过一些配置参数来配置。 在可编程管线的GPU中,你可以写一段程序来表明你想对每一个顶点要做什么样的操作。控制更灵活。

顶点着色器的输入是一个点的各个属性,如该点的坐标、纹理坐标、颜色、法线等。输出是该点转换后的摄像机坐标系坐标、颜色、纹理坐标等。

顶点着色器的输入还包括一些控制项,即图中的Uniforms和Samplers,它们是通过opengl或是direct 3d API提供给着色器程序的,对每个顶点都相同的值。

片元着色器(fragment shader,也叫片段着色器,像素着色器)

现在每个顶点都有了颜色,或是纹理坐标和z坐标。下一步要给面上的每一个点赋予一个颜色和z坐标。

首先要根据显示的分辨率,将面离散化成有限个点。每个点的颜色来源于它所在面的顶点插值,如果采用贴图的话,每个点的纹理坐标来源于顶点的纹理坐标的插值。这些点称为片元或片段。对应着最后有来显示一个像素。

在固定管线的GPU中,插值方式等可以配置。 在可编程的GPU中,片元着色器可以接受一个小程序段,控制这个阶段要做的事情。

片元着色器的输入一个光栅化后一个像素的二维坐标、z坐标、对应的纹理坐标等。 输出是该像素的颜色、z坐标等。

除了着色器程序,后面还需要做的事情:

统一的着色器硬件

无论是顶点着色器还是片元着色器,所要做的操作都是一些浮点数计算。它们有好大一部分操作是共通的。将两个硬件合并成同一个硬件也就合情合理了。

这个统一的着色器硬件称为一个GPU核,这个核很显然可以执行一个程序,做一些浮点运算。在现在GPU中,这样的核的个数是成千上万。相比于CPU,单个CPU的核心个数突破百个的都很少。

对于一些大量数据做同类运算的场景,GPU算得比CPU就要快多了。

下一节将通过opengl和opencl的对比,来看一下一个显卡如何变成计算平台的。