Rendering in different layers

Hello!
I couldn’t find any information about this topic. Or maybe I don’t know how to look for it.
I have created a Vulkan renderer, but how could I render certain objects in differente “layers”?
I don’t know if “layers” is the correct word. In Vulkan, what I would like is, for example, to render the sky in layer 1, some 3D objects in layer 2, and a GUI (or some 3D objects) in layer 3. This way, in the final image that appears in the screen, anything in layer 2 (objects) appears over layer 1 (sky); and everything in layer 3 (GUI or anything) appear over layer 1 & 2.
Is this done with Vulkan? Or maybe it is only done in the shaders or somewhere else? How should it be done? What elements should I touch?
Thank you in advance

Seems trivial. You simply render\vkCmdDraw* the three things in sequence into the same image. Also known as Painter’s Algorithm.

(Or if you want to be uberefficient, then in reverse order, rendering the occluders first with depth bufferering on.)

It doesn’t seem so trivial to me. I mean, we always call vkCmdDraw() in sequence, right? But this way, objects aren’t drawn in layers (like in Painter’s algorithm). When I want to render 3 objects, I call vkCmdDraw three times, once per object, and these objects are drawn in their given 3D positions in the same world, like objects in a videogame, for example, but not like objects in Gimp or Photoshop (which are drawn in layers).
My command buffer is configured in the following way:

vkBeginCommandBuffer(…);
vkCmdBeginRenderPass(…);
for(each model to render)
{
__vkCmdBindPipeline(…);
__vkCmdBindVertexBuffers(…);
__vkCmdBindDescriptorSets(…); // the descriptor set passes the MVP matrix
__vkCmdDraw(…);
}
vkCmdEndRenderPass(…);
vkEndCommandBuffer(…);

As you can see, vkCmdDraw() is called for each object in sequence into the same image. However, no Painter’s algorithm is performed this way.

Well, it is not exactly rocket science either. A vkCmdDraw overwrites whatever was there painted before for each pixel it writes, so by default it acts like a painter. A thing that would prevent this default behavior is depth buffering.

Now, you either do not use depth buffering for a layer, or you just reset a depth buffer between drawing of a layer and a subsequent layer (so no pixel of that layer gets discarded based on depth produced by previous layers).

depthTestEnable and depthWriteEnable are pipeline states that control depth buffering. So it is only a matter of binding appropriate pipeline with that state (which could even be dynamic state with use of an extension.).

Otherwise clering a depth buffer can be done with vkCmdClearAttachments or with beginning a new render pass. Alternatively, one could have multiple depth buffers, and choose the one belonging to a specific layer when starting a new subpass.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.