08/20/2020
立方体贴图数组
创建纹理贴图
//提取信息
cubeMapArray.width = ktxTexture->baseWidth;
cubeMapArray.height = ktxTexture->baseHeight;
cubeMapArray.mipLevels = ktxTexture->numLevels;
cubeMapArray.layerCount = ktxTexture->numLayers;
图像
立方体自带六个面
// Cube faces count as array layers in Vulkan
imageCreateInfo.arrayLayers = 6 * cubeMapArray.layerCount;
// This flag is required for cube map images
imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
拷贝区域
/*
We now copy the parts that make up the cube map array to our image via a command buffer
Cube map arrays in ktx are stored with a layout like this:
- Mip Level 0
- Layer 0 (= Cube map 0)
- Face +X
- Face -X
- Face +Y
- Face -Y
- Face +Z
- Face -Z
- Layer 1 (= Cube map 1)
- Face +X
...
- Mip Level 1
- Layer 0 (= Cube map 0)
- Face +X
...
- Layer 1 (= Cube map 1)
- Face +X
...
*/
// Setup buffer copy regions for each face including all of its miplevels
std::vector<VkBufferImageCopy> bufferCopyRegions;
uint32_t offset = 0;
for (uint32_t face = 0; face < 6; face++) {
for (uint32_t layer = 0; layer < ktxTexture->numLayers; layer++) {
for (uint32_t level = 0; level < ktxTexture->numLevels; level++) {
ktx_size_t offset;
KTX_error_code ret = ktxTexture_GetImageOffset(ktxTexture, level, layer, face, &offset);
assert(ret == KTX_SUCCESS);
VkBufferImageCopy bufferCopyRegion = {};
bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
bufferCopyRegion.imageSubresource.mipLevel = level;
bufferCopyRegion.imageSubresource.baseArrayLayer = layer * 6 + face;
bufferCopyRegion.imageSubresource.layerCount = 1;
bufferCopyRegion.imageExtent.width = ktxTexture->baseWidth >> level;
bufferCopyRegion.imageExtent.height = ktxTexture->baseHeight >> level;
bufferCopyRegion.imageExtent.depth = 1;
bufferCopyRegion.bufferOffset = offset;
bufferCopyRegions.push_back(bufferCopyRegion);
}
}
}
图像视图
// Create the image view for a cube map array
VkImageViewCreateInfo view = vks::initializers::imageViewCreateInfo();
view.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
view.format = format;
view.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
view.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
view.subresourceRange.layerCount = 6 * cubeMapArray.layerCount;
view.subresourceRange.levelCount = cubeMapArray.mipLevels;
view.image = cubeMapArray.image;
VK_CHECK_RESULT(vkCreateImageView(device, &view, nullptr, &cubeMapArray.view));
着色器
片元着色器
#version 450
layout (binding = 1) uniform samplerCubeArray samplerCubeMapArray;
layout (binding = 0) uniform UBO
{
mat4 projection;
mat4 model;
mat4 invModel;
float lodBias;
int cubeMapIndex;
} ubo;
layout (location = 0) in vec3 inUVW;
layout (location = 0) out vec4 outFragColor;
void main()
{
outFragColor = textureLod(samplerCubeMapArray, vec4(inUVW, ubo.cubeMapIndex), ubo.lodBias);
}