66 lines
1.9 KiB
GLSL
66 lines
1.9 KiB
GLSL
#version 430
|
|
|
|
uniform samplerCube SourceTex;
|
|
layout(rgba16f) uniform image2D DestTex;
|
|
uniform ivec2 storeCoord;
|
|
// out vec3 color;
|
|
|
|
#define TWO_PI 6.2831853071795864769252867
|
|
|
|
vec2 hammersley(uint i, uint N) {
|
|
return vec2(float(i) / float(N), float(bitfieldReverse(i)) * 2.3283064365386963e-10);
|
|
}
|
|
|
|
vec3 importance_sample_lambert(vec2 xi) {
|
|
float phi = TWO_PI * xi.x;
|
|
float cos_theta = sqrt(xi.y);
|
|
float sin_theta = sqrt(1 - cos_theta * cos_theta);
|
|
vec3 H;
|
|
H.x = sin_theta * cos(phi);
|
|
H.y = sin_theta * sin(phi);
|
|
H.z = cos_theta;
|
|
return vec3(H);
|
|
}
|
|
|
|
vec3 get_sky_color(vec3 v) {
|
|
return vec3(51, 137, 233) / 255.0 * max(0, v.z) * 0.5;
|
|
}
|
|
|
|
void main() {
|
|
int offs = int(gl_FragCoord.x);
|
|
vec3 direction = vec3(0);
|
|
switch(offs) {
|
|
case 0: direction = vec3(1, 0, 0); break;
|
|
case 1: direction = vec3(-1, 0, 0); break;
|
|
case 2: direction = vec3(0, 1, 0); break;
|
|
case 3: direction = vec3(0, -1, 0); break;
|
|
case 4: direction = vec3(0, 0, 1); break;
|
|
case 5: direction = vec3(0, 0, -1); break;
|
|
}
|
|
|
|
const int num_samples = 512;
|
|
|
|
// Find tangent / binormal
|
|
vec3 v0 = abs(direction.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0);
|
|
vec3 tangent = normalize(cross(v0, direction));
|
|
vec3 bitangent = normalize(cross(tangent, direction));
|
|
|
|
vec3 accum = vec3(0);
|
|
|
|
for (uint i = 0; i < num_samples; ++i) {
|
|
vec2 xi = hammersley(i, num_samples);
|
|
vec3 h = importance_sample_lambert(xi);
|
|
h = normalize(h.x * tangent + h.y * bitangent + h.z * direction);
|
|
|
|
// vec3 l = -reflect(direction, h);
|
|
vec4 sampled_color = textureLod(SourceTex, h, 0);
|
|
accum += sampled_color.xyz * sampled_color.w + get_sky_color(h) * (1 - sampled_color.w);
|
|
}
|
|
|
|
accum /= num_samples;
|
|
|
|
// color = vec3(accum);
|
|
|
|
imageStore(DestTex, ivec2(storeCoord.x * 6 + gl_FragCoord.x, storeCoord.y), vec4(accum, 1));
|
|
}
|