54 lines
1.9 KiB
Plaintext
54 lines
1.9 KiB
Plaintext
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
|
|
|
// Binding for the input skybox cubemap.
|
|
layout(set = 0, binding = 0) uniform samplerCube uSkybox;
|
|
// Binding for the output irradiance (diffuse) cube map stored as a 2D array (each layer is one face).
|
|
#ifdef SHADER_STORAGE_IMAGE_EXTENDED_FORMATS
|
|
layout(set = 0, binding = 1, rgb10_a2) uniform restrict writeonly image2DArray uIrradianceMap;
|
|
#else
|
|
layout(set = 0, binding = 1, rgba8) uniform restrict writeonly image2DArray uIrradianceMap;
|
|
#endif
|
|
|
|
#include "utils/environment_map.glsl"
|
|
|
|
void main()
|
|
{
|
|
ivec2 pix = ivec2(gl_GlobalInvocationID.xy);
|
|
if (pix.x >= pc.size || pix.y >= pc.size) return;
|
|
|
|
// Get normalized UV for current pixel.
|
|
vec2 uv = (vec2(pix) + 0.5) / vec2(pc.size, pc.size);
|
|
int face = int(gl_GlobalInvocationID.z);
|
|
vec3 normal = FaceUVtoDir(face, uv);
|
|
|
|
// Establish a tangent space basis.
|
|
vec3 up = abs(normal.y) < 0.999 ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0);
|
|
vec3 right = normalize(cross(up, normal));
|
|
vec3 tangent = cross(normal, right);
|
|
|
|
vec3 irradiance = vec3(0.0);
|
|
float weight = 0.0;
|
|
uint sampleCount = uint(pc.sampleCount);
|
|
|
|
for (uint i = 0u; i < sampleCount; i++)
|
|
{
|
|
vec2 xi = Hammersley(i, sampleCount);
|
|
// Cosine-weighted hemisphere sampling.
|
|
float phi = 2.0 * PI * xi.x;
|
|
float cosTheta = sqrt(1.0 - xi.y); // weight factor equals cos(theta)
|
|
float sinTheta = sqrt(xi.y);
|
|
vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
|
|
|
|
// Transform sample direction from tangent space to world space.
|
|
vec3 sampleVec = normalize(right * sampleDir.x + tangent * sampleDir.y + normal * sampleDir.z);
|
|
|
|
vec3 sampleColor = texture(uSkybox, sampleVec).rgb;
|
|
irradiance += sampleColor * cosTheta;
|
|
weight += cosTheta;
|
|
}
|
|
irradiance /= weight;
|
|
|
|
imageStore(uIrradianceMap, ivec3(pix, face), vec4(irradiance, 1.0));
|
|
|
|
}
|