openGL 概念学习(二)
一、高级数据处理
1.1 定点数据拷贝(glBufferSubData)
必须在绑定Buffer之后才能使用,从内存中将数据拷贝至指定的显存。
使用问题: 多次修改数据会造成性能浪费,因为每次都要从内存将数据拷贝至显存。
1.2 虚拟指针(glMapBuffer)
必须在VBO构造并且分配空间完毕后使用
其优点在于拷贝了整个显存数据到达内存,修改完毕后再全部同步回显存,适合一个Pass中对数据进行多阶段修改的场景中使用。
二、全局数据块(Uniform Buffer Object)
在编写shader的时候,会发现有很多数据比如VP矩阵是几乎每个shader都可以用到的,但还是需要每次都给各个shader设置,因此引出了Uniform Buffer Object来进行不同shader之间的数据共享,即UBO。
Binding point(绑定点)
在创建Uniform缓冲之后,我们将它绑定到其中一个绑定点上,并将着色器中的Uniform块绑定到相同的绑定点,把它们连接到一起。
如上图所示,可以绑定多个Uniform缓冲到不同的绑定点上。因为着色器A和着色器B都有一个链接到绑定点0的Uniform块,它们的Uniform块将会共享相同的uniform数据,uboMatrices,前提条件是两个着色器都定义了相同的Matrices Uniform块。
为了将Uniform块绑定到一个特定的绑定点中,需要调用glUniformBlockBinding
函数,它的第一个参数是一个程序对象,之后是一个Uniform块索引和链接到的绑定点。Uniform块索引(Uniform Block Index)
是着色器中已定义Uniform块的位置值索引。这可以通过调用glGetUniformBlockIndex
来获取,它接受一个程序对象和Uniform块的名称。我们可以用以下方式将图示中的Lights Uniform块链接到绑定点2
。
unsigned int lights_index = glGetUniformBlockIndex(shaderA.ID, "Lights");
glUniformBlockBinding(shaderA.ID, lights_index, 2);
注意:这里需要对每个着色器重复这一步骤。
接下来,我们还需要绑定Uniform缓冲对象到相同的绑定点上,这可以使用glBindBufferBase或glBindBufferRange来完成。
glBindBufferBase(GL_UNIFORM_BUFFER, 2, uboExampleBlock);
// 或
glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
三、几何着色器
3.1 几何输入方式
点输入方式
图元装配部分不用做任何工作直接将顶点传递给对应的GeometryShader
三角形输入方式
每三个顶点构成一个三角形通过gl_in[]
将顶点数组送入GeometryShader
3.2 几何输出方式
可以输出points, lines, triangles
#version 330 core
layout (points) in;
layout (line_strip, max_vertices = 2) out;
void main() {
gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0);
EmitVertex(); //gl_Position中的向量会被添加到图元中来
gl_Position = gl_in[0].gl_Position + vec4( 0.1, 0.0, 0.0, 0.0);
EmitVertex(); 所有发射出的(Emitted)顶点都会合成为指定的输出渲染图元。
EndPrimitive();
}
3.3 法向量可视化
首先正常绘制场景(不使用几何着色器)。
然后再次绘制场景,只显示通过几何着色器生成法向量。
几何着色器接收一个三角形图元,并沿着法向量生成三条线——每个顶点一个法向量。伪代码看起来会像是这样:
shader.use();
DrawScene();
normalDisplayShader.use();
DrawScene();
为了适配(观察和模型矩阵的)缩放和旋转,我们在将法线变换到裁剪空间坐标之前,先使用法线矩阵变换一次。
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out VS_OUT {
vec3 normal;
} vs_out;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
mat3 normalMatrix = mat3(transpose(inverse(view * model)));
vs_out.normal = normalize(vec3(projection * vec4(normalMatrix * aNormal, 0.0)));
}
关于法线矩阵为何是由MV求逆转置而来的说明:https://blog.csdn.net/Qinhaifu/article/details/102476692
- 点赞
- 收藏
- 关注作者
评论(0)