#include "ibl_common.hlsli" struct Block { uint SkyboxHandle; uint OutputTextureHandle; int CubeSide; }; [[vk::push_constant]] Block pcb; /* | Axis | Layer | Up | |:----:|:-----:|:--:| | +x | 0 | -y | | -x | 1 | -y | | +y | 2 | +z | | -y | 3 | -z | | -z | 4 | -y | | +z | 5 | -y | */ [numthreads(16, 16, 1)] void main(uint3 GlobalInvocationID : SV_DispatchThreadID) { float3 Forward, Up, Right; Forward = GetLocalDir(pcb.CubeSide, GlobalInvocationID); Up = float3(0.0f, 1.0f, 0.0f); // 0.01f offset to Right = normalize(cross(Up, Forward)); Up = normalize(cross(Forward, Right)); float3 Irradiance = 0.0f.xxx; float3 IrrDirr = 0.0f.xxx; float SampleStep = 0.025f; float SampleCount = 0.0f; for (float Azimuth = 0.0f; Azimuth < TAU; Azimuth += SampleStep) { for (float Zenith = 0.0f; Zenith < HALF_PI; Zenith += SampleStep) { float3 DirectionTanSpace = float3(sin(Zenith) * cos(Azimuth), sin(Zenith) * sin(Azimuth), cos(Zenith)); float3 DirectionWorld = DirectionTanSpace.x * Right + DirectionTanSpace.y * Up + DirectionTanSpace.z * Forward; Irradiance += TextureCubes[pcb.SkyboxHandle].SampleLevel(ImmutableSamplers[pcb.SkyboxHandle], DirectionWorld, 0).xyz * (cos(Zenith) * sin(Zenith)); SampleCount++; } } StorageTextureArrays[pcb.OutputTextureHandle][GlobalInvocationID.xyz] = PI * float4(Irradiance * (1.0f / SampleCount), 1.0f); }