0

I want to render a scene with different materials and multiple objects. When I started to implement it myself, I found it difficult to bind material resources before iterating over the objects. I originally plan to use one descriptor set for each material that contains several parameters and textures and pass an array of them to our shader, but this is not possible because the glsl shader requires me to explicitly refer to the descriptor sets and bindings like

location(set = 0, binding = 0) uniform someUniformBuffer/someTextureSampler

Also, the number of descriptor sets and bindings need to be hard-coded into my shader code. Therefore, I do not think it would be possible to do it this way.

After some searching I found two existing ways to bind multiple material resources, basically from SaschaWillems Repo and Vulkan texture rendering on multiple meshes:

  1. Group the faces using the same material of an object, and bind material resources when drawing those faces (You have to do this because the materialId is specified per face). Then the framework would be like
// example for typical loops in rendering
for each view {
  bind view resources          // camera, environment...
  for each shader {
    bind shader pipeline  
    bind shader resources      // shader control values
    for each object {
      bind object resources  // object transforms
      for each material group{
        bind material resources // material parameters and textures
        draw faces
      }
    }
  }
}

This way works on all devices with Vulkan support, but is a little bit complicated because I will have to group the faces by their materialId when building my objects. This is similar to the framework proposed by The NVIDIA Post Vulkan Shader Resource Binding where they group the objects of the same material (In my case I have multiple materials inside the same object).

  1. Use an array of textures and a separate sampler. In this case, I will have a bound for my texture array which could be as low as 128.

  2. Use an array of combined samplers and use

location(set = 0, binding = 0) uniform sampler2DArray

in my shader to deal with an array of textures. This requires the physical device feature shaderSampledImageArrayDynamicIndexing which is not supported by most mobile devices.

In this case, I think I prefer the first method. However, in solution 1, the same material could be bound multiple times for different objects using this material. I am wondering if this would impact the performance and how to improve it considering that each object I want to draw has several materials for different faces.

  • "*the glsl shader requires me to explicitly refer to the descriptor sets and bindings like*" I don't understand why this is a problem. "*could have an impact on performance according to Array of textures performance impact.*" That's the *exact opposite* of what that answer says. – Nicol Bolas Feb 22 '22 at 22:11
  • Overall, this question doesn't really make it clear what "shader resources" are and how they are distinct from "object resources" and "material resources". From the code, I can see the frequency of changes, but I fail to understand what the problem here is. – Nicol Bolas Feb 22 '22 at 22:13
  • @NicolBolas Sorry I think I indeed misunderstood that question about the performance impact of using separate sampler and textures. I'll edit it. As for the glsl descriptor sets and bindings part, I think that prevents me from accessing different descriptor sets with the array index. The material resources refer to material parameters and textures. I have to bind a material multiple times in the pseudo-code if it is used by multiple objects, I am wondering whether this would induce performance issues. – LonelyQuantum Feb 22 '22 at 22:25
  • @NicolBolas The reason I think it would be bad to bind textures multiple times is that I think they have a lot higher bandwidth than some transform matrices for a single object. That is why I want to bind the materials once and refer to them using the material index in my shader code. However, this involves how descriptor binding works. Whether it is worse to bind a lot of resources at one time, or it is worse to call the descriptor set binding API a lot of times. – LonelyQuantum Feb 22 '22 at 22:55

0 Answers0