OpenGL在不同着色器之间传递数据

通过上一篇的动态移动的三角形,知道关键字inout的用法之后,可以动态的改变三角形渲染的位置(也就是改变了动态改变顶点坐标了),咱们知道这个三角形的颜色是在片段着色器里面进行控制的,那是不是也可以动态的去控制这个颜色。

那就捋一捋,通过OpenGL管线咱们知道,数据会先进入顶点着色器,最后才到片段着色器中,那么,要能动态改变片段着色器中的颜色,这个数据还是得先能进入顶点着色器中,通过inout关键字,就可以在顶点着色器中写出如下代码

#version 450 core

layout(location = 0) in vec4 offset;
layout(location = 1) in vec4 color;

out vec4 vs_color;

void main(void) {
    vs_color = color;
}

第四行用in关键字声明了color,用于接收输入的color,在第六行使用out声明的vs_color作为输出,输出到后续管线之中。想想咱们在编写第一个片段着色器的时候,是不是也使用了out声明了一个color属性,原理是一样的。

接着再在片段着色器中,我们接收这个vs_color

#version 450 core

in vec4 vs_color;

out vec4 color;

void main(void) {
    color = vs_color;
}

最后咱们再在render()中,将color属性添加到index为1的上面,前面定义的location = 1

void render(double currentTime) {
    const GLfloat vs_color[] = { (float)sin(currentTime) * 0.2f + 0.5f,
									(float)cos(currentTime) * 0.3f + 0.7f,
								  0.0f, 1.0f };
	glVertexAttrib4fv(1, vs_color);
}

这样便能动态的改变三角形的颜色了

注意:在顶点着色器中用out声明的vs_color,会在片段着色器中与一个用in声明vs_color进行匹配,也就是这两个变量名必须一致!

接口块

前面咱们是每次声明一个接口变量,这是最简单的方式。但是实际应用中可能会需要传递大量不同的数据段,包括数组、结构甚至其他复杂排列的变量。那么就可以将大量变量集合为一个接口块(interface block)。声明类似结构体,同样也是使用inout进行声明

#version 450 core
layout(location = 0) in vec4 offset;
layout(location = 1) in vec4 color;
out VS_OUT
{
    vec4 color;
} vs_out;

void main(void) {
    vs_out.color = color;
}

代码的4-7行就是一个接口块out后的VS_OUT为块名称,vs_out为实例名称。而接口块在各个阶段通过块名称进行匹配,在着色器中通过实例进行引用,那么对应在片段着色器中的使用则如下所示

#version 450 core

in VS_OUT
{
    vec4 color;
} fs_in;

out vec4 color;

void main(void) {
    color = fs_in.color;
}

这便是整个接口块,接口块可用于在各个阶段移动数据,但是不能使用这些接口块将输入集合到顶点着色器中,或将在片段着色器中将输出集合到一块。

猜你喜欢

转载自blog.csdn.net/dl15600383645/article/details/127758391
今日推荐