Link

我们已经能够渲染一个红色三角形,但这太无聊了。现在,我们将为其添加更多颜色,将其转换为经典的 RGB 三角形。

为此,我们需要从顶点着色器向片段着色器传递更多数据。目前我们只传递位置,这是一个默认的 Vulkan 变量,但是没有我们可以使用的颜色变量,所以我们需要创建我们自己的。

所有着色器阶段都可以通过使用输入和输出变量在它们之间传递数据。如果在顶点着色器中创建一个输出变量,我们就可以在片段着色器中将其作为输入变量读取。

一个非常重要的细节是,当编译使用这种输入和输出变量的管线时,它们必须始终匹配。如果存在不匹配,管线编译将失败。

要创建输出变量,我们在顶点着色器中执行此操作。

layout (location = 0) out vec3 outColor;

layout(location = 0) 是一个装饰器,允许我们向 GLSL 中的变量声明和其他内容添加“额外数据”。在这里,我们声明 location = 0,这意味着 vec3 类型的此变量将位于编号为 0 的槽位上。

要从像素阶段读取变量,我们执行此操作。

layout (location = 0) in vec3 inColor;

变量的名称不需要匹配。在顶点着色器中,我们将其称为 outColor,但在片段着色器中,我们将其称为 inColor。需要匹配的是 Location 装饰器和变量的类型。在这种情况下,它是位置 0 vec3 变量,因此它们匹配。

我们可以从顶点着色器输出大多数默认类型到片段着色器,但要小心,因为需要在阶段之间传递的数据越多,开销就越大。旧的 GPU 甚至对可以传递的变量数量有非常小的限制。

现在我们知道了如何从顶点着色器向片段着色器传递数据,让我们用它来创建一个彩色三角形。

顶点着色器

创建一个新的着色器,名为 colored_triangle.vert。它将与 triangle.vert 着色器基本相同,但带有颜色。

//output variable to the fragment shader
layout (location = 0) out vec3 outColor;

void main()
{
	//const array of positions for the triangle
	const vec3 positions[3] = vec3[3](
		vec3(1.f,1.f, 0.0f),
		vec3(-1.f,1.f, 0.0f),
		vec3(0.f,-1.f, 0.0f)
	);

	//const array of colors for the triangle
	const vec3 colors[3] = vec3[3](
		vec3(1.0f, 0.0f, 0.0f), //red
		vec3(0.0f, 1.0f, 0.0f), //green
		vec3(00.f, 0.0f, 1.0f)  //blue
	);

	//output the position of each vertex
	gl_Position = vec4(positions[gl_VertexIndex], 1.0f);
	outColor = colors[gl_VertexIndex];
}

与我们处理位置的方式相同,我们声明一个颜色常量数组,红色、绿色和蓝色,然后将它们输出到 outColor 变量。

片段着色器

创建一个新的着色器,名为 colored_triangle.frag

#version 450

//shader input
layout (location = 0) in vec3 inColor;

//output write
layout (location = 0) out vec4 outFragColor;


void main()
{
	//return color
	outFragColor = vec4(inColor,1.0f);
}

我们现在可以在片段着色器中读取颜色,并将其作为最终颜色输出。

确保在 Cmake 中重建 Shaders 目标,因为我们需要它来编译新内容。它应该没有任何错误

在代码中更改着色器

现在,让我们更改代码中使用的着色器,将红色三角形着色器切换为彩色三角形着色器。

在加载三角形着色器的代码中,我们更改文件名

 VkShaderModule triangleFragShader;
    if (!load_shader_module("../../shaders/colored_triangle.frag.spv", &triangleFragShader))
    {
        std::cout << "Error when building the triangle fragment shader module" << std::endl;
    }
    else {
        std::cout << "Triangle fragment shader successfully loaded" << std::endl;
    }

    VkShaderModule triangleVertexShader;
    if (!load_shader_module("../../shaders/colored_triangle.vert.spv", &triangleVertexShader))
    {
        std::cout << "Error when building the triangle vertex shader module" << std::endl;

    }
    else {
        std::cout << "Triangle vertex shader successfully loaded" << std::endl;
    }

如果您编译并运行,您现在应该看到一个彩色的 RGB 三角形

triangle

下一步: 切换着色器