Cubemap Conversion (π WIP)ΒΆ
Resulting code: step220
ProblemΒΆ
Remember the cube maps from the Image-Based Lighting chapter? We can actually build them from the equirectangular environment maps found for instance on PolyHaven or ambientCG.
Input:
Parameterization:
Output:
Since it is easier to find equirectangular images, but a cubemap is faster to query (because it is accelerated by the hardware), our goal is to convert an equirectangular image to a cubemap.
ImplementationΒΆ
TODO
// The output is a square texture with 6 layers, one per face of the cube
textureDesc.size = { (uint32_t)height, (uint32_t)height, 6 };
m_outputTexture = m_device.createTexture(textureDesc);
// We create 1 view per face of the cube (i.e., per layer of the output texture)
// NB: This is only used when drawing the GUI
std::array<wgpu::TextureView, 6> m_outputTextureLayers = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
const char* outputLabels[] = {
"Output Positive X",
"Output Negative X",
"Output Positive Y",
"Output Negative Y",
"Output Positive Z",
"Output Negative Z",
};
for (uint32_t i = 0; i < 6; ++i) {
textureViewDesc.label = outputLabels[i];
textureViewDesc.baseArrayLayer = i;
m_outputTextureLayers[i] = m_outputTexture.createView(textureViewDesc);
}
// We still use the view that covers all layers, because we will draw all of
// them in a single dispatch.
textureViewDesc.baseArrayLayer = 0;
textureViewDesc.arrayLayerCount = 6;
textureViewDesc.dimension = TextureViewDimension::_2DArray;
m_outputTextureView = m_outputTexture.createView(textureViewDesc);
In the bind group layout, we switch the texture dimension to 2DArray
:
bindings[1].storageTexture.viewDimension = TextureViewDimension::_2DArray;
// ^ This was _2D
In the shader, we must change the type or outputTexture
:
@group(0) @binding(1) var outputTexture: texture_storage_2d_array<rgba8unorm,write>;
// ^ This was texture_storage_2d
The call to textureStore
then takes a new argument, the layer in which we write:
let layer = id.z;
textureStore(outputTexture, id.xy, layer, color);
We launch 4 * 4 * 6 = 96 = 3 * 32
threads:
@compute @workgroup_size(4, 4, 6)
uint32_t invocationCountX = m_outputTexture.getWidth();
uint32_t invocationCountY = m_outputTexture.getHeight();
uint32_t workgroupSizePerDim = 4;
TODO
ConclusionΒΆ
Resulting code: step220