#version 430
////////////////////////////////////////////////////////////////////////////////
// <copyright>
// Copyright (c) 2015 Hue AS. All rights reserved.
//
// All rights are reserved. Reproduction or transmission in whole or in part, in
// any form or by any means, electronic, mechanical or otherwise, is prohibited
// without the prior written permission of the copyright owner.
// </copyright>
////////////////////////////////////////////////////////////////////////////////

#define REDUCE_FACTOR $REDUCE_FACTOR$

layout(binding = 0) uniform usampler2D fragmentCount;
layout(binding = 1) uniform usampler2D fragmentOffset;
layout(binding = 2) uniform sampler2D fragmentColor;
layout(binding = 3) uniform sampler2D fragmentDepth;
layout(binding = 4) uniform usampler2D fragmentStencil;
layout(binding = 5) uniform usampler2D volumeProbeDepth;

uniform uint pitch;
uniform uint alignment;

layout(pixel_center_integer) in vec4 gl_FragCoord;
layout(location = 0) out vec4 color;

ivec2 indexToPos(uint index)
{
  return ivec2(index % (pitch / REDUCE_FACTOR), index / (pitch / REDUCE_FACTOR)) * REDUCE_FACTOR + ivec2(gl_FragCoord.xy) % REDUCE_FACTOR;
}

void main()
{
  uint count = texelFetch(fragmentCount, ivec2(gl_FragCoord.xy), 0).x;
  if (count == 0u) discard;

  uint offset = texelFetch(fragmentOffset, ivec2(gl_FragCoord.xy), 0).x - alignment - count;

  gl_FragDepth = uintBitsToFloat(texelFetch(volumeProbeDepth, ivec2(gl_FragCoord.xy), 0).x);
  color = vec4(0.0);

  for (uint layer = 0u; layer < count && color.w < 0.9961; ++layer)
  {
    ivec2 pos = indexToPos(offset + layer);
    float depth = texelFetch(fragmentDepth, pos, 0).x;
    if (depth >= 0.0)
    {
      gl_FragDepth = min(gl_FragDepth, depth); // If 'depth' < 0, then this layer is a volume probe surface, and the depth comes from 'volumeProbeDepth'.
    }
    // If the layer is a regular surface, or if the layer is a volume probe surface that has been processed, then apply color.
    if (depth >= 0.0 || texelFetch(fragmentStencil, pos, 0).x != 0)
    {
      color += texelFetch(fragmentColor, pos, 0) * (1.0 - color.w);
    }
  }
}
