渲染多种不同的材质,这些材质有时会要求使用不同的着色器配置

时间:2018-09-22 16:40:28

标签: glsl shader vulkan

我正在尝试构建基于3D体素的游戏引擎,以学习如何使用vulkan。我碰到一堵墙,找不到关于如何攀登的文档。现在,我正在绘制2D三角形并将其在屏幕上移动,我的2D三角形在顶点缓冲区中定义为1个顶点,将来将在顶点着色器中转换为屏幕空间。我的几何着色器将单个顶点变成3个顶点,然后传递给我的片段着色器。

    triangle_center_position[0] = (cursor_x - (vulkan_window_width_get() / 2.0f)) / vulkan_window_width_get();
    triangle_center_position[1] = (cursor_y - (vulkan_window_height_get() / 2.0f)) / vulkan_window_height_get();
    // send to gpu via memory mapped region
    memcpy(triangle_position_buffer.mapped_memory, &triangle_center_position, sizeof(vec2) * 1);

它通过以下方式绑定在命令缓冲区中:

    VkBuffer vertexBuffers[] = {buffer->buffer};
    VkDeviceSize offsets[] = {0};
    vkCmdBindVertexBuffers(command_buffer[i], 0, 1, vertexBuffers, offsets);
    vkCmdDraw(command_buffer[i], (uint32_t) buffer->num_elements, 1, 0, 0);

我的计划是最终修改此代码以包含3D点,并使我的几何体着色器将3D点扩展为体素。

不幸的是,我只希望这种转换发生在体素世界中的块上,而不是其他事物(玩家模型等)上。

在OpenGL中,我只是在针对不同“材质”构建的两个着色器程序上调用glUseProgram(),在vulkan中似乎极力劝阻。我的直觉就是这样

currentMaterial = null
for (Renderable r : sort(everything, by material type)) 
    if (!r.isWithinViewOfScreen()) 
        continue
    if (r.material != currentMaterial)
        currentMaterial = r.material
        r.material.use()
    r.render()

主要问题是某些Renderable将使用完全不同的着色器要求,但是vulkan中似乎没有提供在着色器程序之间交换的规定。

1 个答案:

答案 0 :(得分:2)

  

vulkan中似乎没有在着色器程序之间交换的规定。

在vulkan中与glUseProgram最接近的类似物是vkCmdBindPipeline

主要区别在于,许多被认为是OpenGL状态机一部分的东西都被烘焙到Vulkan流水线对象中。因此,例如,在OpenGL上,您可以调用glUseProgram,渲染一些内容,然后调用glDisable(GL_DEPTH_TEST)并渲染更多内容,在Vulkan上,这将是两个不同的管道,并且需要调用{{ 1}}。

如果您熟悉vkCmdBindPipeline,并且正在寻找某种方法来修改哪些着色器,那么简短的答案是您不能这样做。您需要为需要使用的每组着色器创建一个完整的VkPipeline对象,即使管道中的其他任何值都不同。

但是,如果您担心最终将创建大量管道,并且这会影响您的性能,则应研究管道缓存的使用以及VK_PIPELINE_CREATE_DERIVATIVE_BIT标志,该标志可让您创建类似于模板管道中的子管道。与从OpenGL获得的性能相同或更好。

编辑:

请记住,试图提高管道创建性能的开发人员应同时使用vkCmdBindPipelineVkPipelineCache的功能。派生管道对您有多少帮助完全取决于驱动程序,并且某些驱动程序(例如ARM MALI驱动程序)被明确记录为忽略此标志。 Vulkan规范并未就何时使用或不使用派生标志提供任何指导。正确的方法可能是直接与ISV合作以找出如何最好地应用它,或者总是使用它,以期希望它会在不影响性能的情况下提高性能,或者根本不使用派生工具。 。

另一方面,管道缓存功能几乎可以肯定会在各种硬件上缩短管道创建时间。