#include "bindless_structs.hlsli" /* The Goal is simply to convert from a (0,0,0) to (CubeSide, CubeSide, FaceCount) Invocation ID space to a (-1,-1,-1) to (1, 1, 1) space. | Axis | Layer | Up | |:----:|:-----:|:--:| | +x | 0 | -y | | -x | 1 | -y | | +y | 2 | +z | | -y | 3 | -z | | -z | 4 | -y | | +z | 5 | -y | */ float3 GetCubeDir(uint3 GlobalInvocationID, float SideLength) { float2 FaceUV = float2(GlobalInvocationID.xy) / SideLength; // (0, SideLength) -> (0, 1) FaceUV = 2.0f * FaceUV - 1.0f; // (0, 1) -> (-1, 1) switch (GlobalInvocationID.z) { case 0: return normalize(float3(1.0f, -FaceUV.y, -FaceUV.x)); // Face +X; x = 1, y = -v, z = -u case 1: return normalize(float3(-1.0f, -FaceUV.y, FaceUV.x)); // Face -X; x = -1, y = -v, z = u case 2: return normalize(float3(FaceUV.x, 1.0f, FaceUV.y)); // Face +Y; x = u, y = 1, z = v case 3: return normalize(float3(FaceUV.x, -1.0f, -FaceUV.y)); // Face -Y; x=u, y=-1, z=-v case 4: return normalize(float3(FaceUV.x, -FaceUV.y, 1.0f)); // Face +Z; x=u,y=-v, z=1 case 5: return normalize(float3(-FaceUV.x, -FaceUV.y, -1.0f)); // Face -Z; x=u,y=-v, z=-1 default: // Never reach here. return 0.0f.xxx; } } float RadicalInverse_VdC(uint Bits) { Bits = (Bits << 16u) | (Bits >> 16u); Bits = ((Bits & 0x55555555u) << 1u) | ((Bits & 0xAAAAAAAAu) >> 1u); Bits = ((Bits & 0x33333333u) << 2u) | ((Bits & 0xCCCCCCCCu) >> 2u); Bits = ((Bits & 0x0F0F0F0Fu) << 4u) | ((Bits & 0xF0F0F0F0u) >> 4u); Bits = ((Bits & 0x00FF00FFu) << 8u) | ((Bits & 0xFF00FF00u) >> 8u); return float(Bits) * 2.3283064365386963e-10; // / 0x100000000 } float2 Hammersley(uint SampleIndex, uint SampleCount) { return float2(float(SampleIndex) / float(SampleCount), RadicalInverse_VdC(SampleIndex)); } float3 ImportanceSampleGGX(float2 Xi, float3 Normal, float Roughness) { float A = Roughness * Roughness; float Phi = 2.0f * PI * Xi.x; float CosTheta = sqrt((1.0f - Xi.y) / (1.0f + (A * A - 1.0f) * Xi.y)); float SinTheta = sqrt(1.0f - CosTheta * CosTheta); // from spherical coordinates to cartesian coordinates float3 H; H.x = cos(Phi) * SinTheta; H.y = sin(Phi) * SinTheta; H.z = CosTheta; // from tangent-space vector to world-space sample vector float3 Up = abs(Normal.z) < 0.999f ? float3(0.0f, 0.0f, 1.0f) : float3(1.0f, 0.0f, 0.0f); float3 Tangent = normalize(cross(Up, Normal)); float3 Bitangent = cross(Normal, Tangent); float3 SampleVec = Tangent * H.x + Bitangent * H.y + Normal * H.z; return normalize(SampleVec); }