
#include "/lib/noise_common.glsl"
#include "/lib/noise_options.glsl"
#include "/lib/noise_render_scale.glsl"

#if BLOOM == 1 && BLOOM_RESOLUTION == 0
const vec2 workGroupsRender = vec2(0.5, 0.5);
#else
const ivec3 workGroups = ivec3(1, 1, 1);
#endif
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;

uniform sampler2D colortex0;
uniform float viewWidth;
uniform float viewHeight;
uniform vec3 sunPosition;
uniform mat4 gbufferModelView;
uniform int isEyeInWater;

layout(rgba16f) writeonly uniform image2D noise_bloom_img;

vec2 noiseBloomSourceUv(vec2 logicalUv, vec2 fullSize) {
	vec2 scale = noiseRenderScale2(fullSize);
	vec2 halfPixel = 0.5 / fullSize;
	return clamp(logicalUv * scale, halfPixel, scale - halfPixel);
}

vec3 noiseBloomSample(vec2 logicalUv, vec2 fullSize) {
	return texture(colortex0, noiseBloomSourceUv(logicalUv, fullSize)).rgb;
}

void main() {
	#if BLOOM == 0 || BLOOM_RESOLUTION != 0
	return;
	#else
	ivec2 bloomPixel = ivec2(gl_GlobalInvocationID.xy);
	ivec2 bloomSize = imageSize(noise_bloom_img);
	if (any(greaterThanEqual(bloomPixel, bloomSize))) return;

	vec2 fullSize = vec2(viewWidth, viewHeight);
	vec2 logicalUv = (vec2(bloomPixel) + 0.5) / vec2(bloomSize);
	vec2 pixel = 1.0 / fullSize;
	vec3 blur = vec3(0.0);
	blur += noiseBloomSample(logicalUv + vec2( pixel.x, 0.0), fullSize);
	blur += noiseBloomSample(logicalUv + vec2(-pixel.x, 0.0), fullSize);
	blur += noiseBloomSample(logicalUv + vec2(0.0,  pixel.y), fullSize);
	blur += noiseBloomSample(logicalUv + vec2(0.0, -pixel.y), fullSize);
	blur *= 0.25;

	vec2 wide = pixel * 7.0;
	vec3 wideBlur = vec3(0.0);
	wideBlur += noiseBloomSample(logicalUv + vec2( wide.x, 0.0), fullSize);
	wideBlur += noiseBloomSample(logicalUv + vec2(-wide.x, 0.0), fullSize);
	wideBlur += noiseBloomSample(logicalUv + vec2(0.0,  wide.y), fullSize);
	wideBlur += noiseBloomSample(logicalUv + vec2(0.0, -wide.y), fullSize);
	wideBlur += noiseBloomSample(logicalUv + vec2( wide.x,  wide.y), fullSize);
	wideBlur += noiseBloomSample(logicalUv + vec2(-wide.x,  wide.y), fullSize);
	wideBlur += noiseBloomSample(logicalUv + vec2( wide.x, -wide.y), fullSize);
	wideBlur += noiseBloomSample(logicalUv + vec2(-wide.x, -wide.y), fullSize);
	wideBlur *= 0.125;

	float daylight = noiseDaylight(sunPosition, gbufferModelView);
	float nightFactor = noiseNight(daylight);
	float bloomMask = smoothstep(0.90, 1.80, dot(blur, NOISE_LUMA));
	float nightBloomMask = smoothstep(0.72, 1.55, dot(wideBlur, NOISE_LUMA));
	float bloomMedium = isEyeInWater == 0 ? 1.0 : (isEyeInWater == 1 ? 0.24 : 0.34);
	vec3 contribution = blur * bloomMask * mix(0.055, 0.10, nightFactor);
	contribution += wideBlur * nightBloomMask * nightFactor * 0.105;
	imageStore(noise_bloom_img, bloomPixel,
		vec4(contribution * bloomMedium, 1.0));
	#endif
}
