OpenGL顶点着色器与VBO,VAO

(一)着色器(Shader)

随着GPU的发展,GPU加入了可编程处理器(shader),开发人员可直接控制GPU的行为。shader出现之后,GPU上增加可编程处理器,就有类似GLSL的GPU编程语言。

所谓Shader,就是控制GPU的一堆指令集,程序员写出shader,输入到GPU中,GPU执行。也可以理解为opengl实现了一种可以让点和像素的计算在GPU中进行的规范,这就是着色器,编写着色器的规范就是GLSL

 

早期的Shader是直接使用汇编, 后来OpenGL ARB组织开发了一种新的编程语言,叫做GLSL(OpenGL shading language). 该语言类似于C风格,程序员们就可以很方便的写出可直接控制GPU的代码了。 

所谓控制GPU,就是控制GPU的处理器,现阶段,GPU有以下几个处理器: 

1. Vertext processor(顶点处理器)

2. Tessellation Control processor(曲面控制处理器)

3. Tessellation Evaluation processor(曲面细分处理器)

4. Geometry processor(几何处理器)

5. Fragment processor(片元处理器)

于是,shader就分为:

1. Vertext shader(顶点着色器)

2. Tessellation Control shader(曲面控制着色器)

3. Tessellation Evaluation shader(曲面细分着色器)

4. Geometry shader(几何着色器)

5. Fragment shader(片元着色器) 

 GLSL的数据定义

  
基础数据类型 int
floatdoubleuintbool
向量 vecn 包含n个float分量的默认向量
bvecn 包含n个bool分量的向量ivecn 包含n个int分量的向量uvecn 包含n个unsigned int分量的向量dvecn 包含n个double分量的向量---------------------------------------------------------向量是一个可以包含有2、3或者4个分量的容器(n代表分量的数量)
向量的分量 vec4 : vec.x vec.y vec.z vec.w
bvec4 : bvec.x bvec.y bvec.z bvec.w...---------------------------------------------------------这里x是指这个向量的第一个分量。你可以分别使用.x、.y、.z和.w来获取它们的第1、2、3、4个分量
重组 vec2 someVec= vec2(0.1, 0.2);
vec3 someVec= differentVec.zyw;vec3 someVec= differentVec.xxx;vec4 someVec= differentVec.xxxx+otherVec.xyzw;vec4 someVec= vec4(differentVec.xyz, 1.0);---------------------------------------------------------可以使用向量的任意分量的任意组合来创建一个和原来向量一样长的(同类型)新向量
位置变量的属性位置值 layout (location = 0) in vec3 aPos
---------------------------------------------------------常用于顶点着色器,设置外部输入数据的位置变量的属性位置值,上面展示了外部数据aPos的位置变量属性值为0。
输入数据 in vec3 aPos
---------------------------------------------------------
输出数据 out vec4 FragColor
---------------------------------------------------------
uniform uniform vec4 ourColor
---------------------------------------------------------uniform可以理解为一个in,但它是全局的,且它可以从CPU中向GPU中的着色器发送数据,具体我们会在后文展开来讲。

 

(1)顶点着色器

    它会在GPU上创建内存,用于存储我们的顶点数据。通过顶点缓冲对象(Vertex BufferObjects,VBO)管理,顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER

    VAO和VBO都是用来存储顶点信息的,并把这些信息送入顶点着色器。
    VBO的B为Buffer之意,用来存储顶点数据;VAO的A为Array,但我认为理解为 Attribute(属性) 之意更好,意思是 Buffer(VBO)的属性。 
    即,我们用VBO来存储数据,而用VAO来告诉计算机这些数据分别有什么属性、起什么作用。  

(二)VBO与VAO

  

 补充:

布局限定符(GLSL除了这个限定符,还有很多其它限定符,比如存储限定符、内存限定符、插值限定符等,具体参看https://www.khronos.org/opengl/wiki/Type_Qualifier_(GLSL)),基本语法为:

layout(qualifier1​, qualifier2​ = value, ...) variable definition 

主要有以下用法:

1、用于着色器输入/输出变量接口布局

着色器的输入/输出变量就是着色器与显存或其它着色器通信的接口,通过layout可以指定这些输入/输出变量从哪去什么值/向哪输出什么值。

1.1、顶点着色器的属性索引

layout(location = attribute index) in vec3 position;
可以指定顶点着色器输入变量使用的顶点属性索引值,一般在glVertexAttribPointer中指定属性索引值。如果同时使用了glBindAttribLocation,那么这个layout优先。

如果输入变量占用了多个属性位置槽,那么将按照属性位置顺序依次分配,如

layout(location = 2) in vec3 values[4];
values将依次获取属性位置2,3,4,5处的值。 

标准化设备坐标(Normalized Device Coordinates, NDC)
一旦你的顶点坐标已经在顶点着色器中处理过,它们就应该是标准化设备坐标了,标准化设备坐标是一个x、y和z值在-1.0到1.0的一小段空间。落在坐标范围之外的都会被裁剪。

你的标准化设备坐标接着会变换为屏幕空间坐标(Screen-space Coordinates),这是使用你通过glViewport函数提供的数据,进行视口变换(Viewport Transform)完成的。所得的屏幕空间坐标又会被变换为片段输入到片段着色器中。 

 

参考资料:

learnopengl

  

posted @ 2022-07-30 18:18  安静点--  阅读(493)  评论(0编辑  收藏  举报