使用光线追踪实现纹理映射的常规方法是什么?
What are the normal methods for achiving texture mapping with raytracing?
创建 BLAS(底层加速结构)时,您指定任意数量的 vertex/index 缓冲区作为结构的一部分。它如何最终与着色器交互并在描述符集中指定?我应该如何link这些结构用材料?
纹理映射通常如何使用光线追踪完成?我在 Q2RTX 中看到了某种“材料 table”,但文档不存在,代码也很少注释。
一种常见的方法是将 material 缓冲区与纹理数组结合使用,该数组在您需要纹理数据的着色器中寻址。然后你传递 material id 例如每个顶点或每个图元,然后使用它来动态获取 material,并使用它获取纹理索引。由于 Vulkan 光线追踪的要求,您可以使用 VK_EXT_descriptor_indexing
扩展 (Spec) 来简化此操作,这使得创建包含渲染场景所需的所有纹理的大型描述符集成为可能。
相关着色器部分:
// Enable required extension
...
#extension GL_EXT_nonuniform_qualifier : enable
// Material definition
struct Material {
int albedoTextureIndex;
int normalTextureIndex;
...
};
// Bindings
layout(binding = 6, set = 0) readonly buffer Materials { Material materials[]; };
layout(binding = 7, set = 0) uniform sampler2D[] textures;
...
// Usage
void main()
{
Primitive primitive = unpackTriangle(gl_Primitive, ...);
Material material = materials[primitive.materialId];
vec4 color = texture(textures[nonuniformEXT(material.albedoTextureIndex)], uv);
...
}
然后在您的应用程序中创建一个缓冲区来存储在主机上生成的 materials,并将其绑定到着色器的绑定点。
对于纹理,您将它们作为纹理数组传递。数组纹理也是一种选择,但由于每个数组切片的大小限制相同,因此不够灵活。请注意,它在上面的示例中没有大小限制,这是通过 VK_EXT_descriptor_indexing
实现的,并且只允许用于描述符集中的最终绑定。这为您的设置增加了一些灵活性。
至于传递您从中获取数据的 material 索引:最简单的方法是将该信息与您的顶点数据一起传递,您必须 access/unpack无论如何着色器:
struct Vertex {
vec4 pos;
vec4 normal;
vec2 uv;
vec4 color;
int32_t materialIndex;
}
创建 BLAS(底层加速结构)时,您指定任意数量的 vertex/index 缓冲区作为结构的一部分。它如何最终与着色器交互并在描述符集中指定?我应该如何link这些结构用材料?
纹理映射通常如何使用光线追踪完成?我在 Q2RTX 中看到了某种“材料 table”,但文档不存在,代码也很少注释。
一种常见的方法是将 material 缓冲区与纹理数组结合使用,该数组在您需要纹理数据的着色器中寻址。然后你传递 material id 例如每个顶点或每个图元,然后使用它来动态获取 material,并使用它获取纹理索引。由于 Vulkan 光线追踪的要求,您可以使用 VK_EXT_descriptor_indexing
扩展 (Spec) 来简化此操作,这使得创建包含渲染场景所需的所有纹理的大型描述符集成为可能。
相关着色器部分:
// Enable required extension
...
#extension GL_EXT_nonuniform_qualifier : enable
// Material definition
struct Material {
int albedoTextureIndex;
int normalTextureIndex;
...
};
// Bindings
layout(binding = 6, set = 0) readonly buffer Materials { Material materials[]; };
layout(binding = 7, set = 0) uniform sampler2D[] textures;
...
// Usage
void main()
{
Primitive primitive = unpackTriangle(gl_Primitive, ...);
Material material = materials[primitive.materialId];
vec4 color = texture(textures[nonuniformEXT(material.albedoTextureIndex)], uv);
...
}
然后在您的应用程序中创建一个缓冲区来存储在主机上生成的 materials,并将其绑定到着色器的绑定点。
对于纹理,您将它们作为纹理数组传递。数组纹理也是一种选择,但由于每个数组切片的大小限制相同,因此不够灵活。请注意,它在上面的示例中没有大小限制,这是通过 VK_EXT_descriptor_indexing
实现的,并且只允许用于描述符集中的最终绑定。这为您的设置增加了一些灵活性。
至于传递您从中获取数据的 material 索引:最简单的方法是将该信息与您的顶点数据一起传递,您必须 access/unpack无论如何着色器:
struct Vertex {
vec4 pos;
vec4 normal;
vec2 uv;
vec4 color;
int32_t materialIndex;
}