77 lines
2.7 KiB
HLSL
77 lines
2.7 KiB
HLSL
#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);
|
|
} |