OpenGL着色语言
接口块
从顶点着色器向片段着色器发送数据时,可以声明几个对应的输入/输出变量。将它们一个一个声明是着色器间发送数据最简单的方式了,但当程序变得更大时,希望发送的可能就不只是几个变量了,它还可能包括数组和结构体;为了帮助我们管理这些变量,GLSL为我们提供了一个叫做接口块(Interface Block)的东西,来方便我们组合这些变量。接口块的声明和struct的声明有点相像,不同的是,现在根据它是一个输入还是输出块(Block),使用in或out关键字来定义的。
//顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out VS_OUT
{
vec2 TexCoords;
} vs_out;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
vs_out.TexCoords = aTexCoords;
}
//片元着色器
#version 330 core
out vec4 FragColor;
in VS_OUT
{
vec2 TexCoords;
} fs_in;
uniform sampler2D texture;
void main()
{
FragColor = texture(texture, fs_in.TexCoords);
}
Uniform缓冲对象
OpenGL提供了一个叫做Uniform缓冲对象(Uniform Buffer Object)的工具,它允许我们定义一系列在多个着色器中相同的全局Uniform变量。当使用Uniform缓冲对象的时候,我们只需要设置相关的uniform一次。当然,我们仍需要手动设置每个着色器中不同的uniform。并且创建和配置Uniform缓冲对象会有一点繁琐。
因为Uniform缓冲对象是一个缓冲,可以使用glGenBuffers来创建它,将它绑定到GL_UNIFORM_BUFFER缓冲目标,并将所有相关的uniform数据存入缓冲。
GLuint ubo;
glGenBuffers(1,&ubo);
glBindBuffer(GL_UNIFORM_BUFFER,ubo);
glBufferData(GL_UNIFORM_BUFFER,size,buffer,GL_STATIC_RAW);
//顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
//将projection和view矩阵存储到Uniform块(Uniform Block)中:
//std140:定义的Uniform块对它的内容使用一个特定的内存布局。
layout (std140) uniform Matrices
{
mat4 projection;
mat4 view;
};
uniform mat4 model;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
Uniform块布局
uniform 块的内容是储存在一个缓冲对象中,它实际只是一块预留内存。因为这块内存并不会保存它具体保存的是什么类型的数据,我们需要告诉openGL内存的哪一部分对应着着色器中的哪一个uniform变量。
layout (std140) uniform ExampleBlock
{
float value;
vec3 vector;
mat4 matrix;
float values[3];
bool boolean;
int integer;
};

1. shared
默认情况下,GLSL会使用

本文详细介绍了OpenGL着色语言(GLSL)中的接口块概念,包括如何使用接口块在顶点着色器和片段着色器之间传递复杂数据结构,如数组和结构体。此外,还探讨了Uniform缓冲对象的创建和使用,以及Uniform块布局的不同选项,如共享、紧凑、std140和std430布局。
最低0.47元/天 解锁文章
1894





