let GAMMA = 2.200000048;

fn linearTosRGB(linear : vec3<f32>) -> vec3<f32> {
  let INV_GAMMA = (1.0 / GAMMA);
  return pow(linear, vec3(INV_GAMMA));
}

fn sRGBToLinear(srgb : vec3<f32>) -> vec3<f32> {
  return pow(srgb, vec3(GAMMA));
}

struct Camera {
  projection : mat4x4<f32>;
  inverseProjection : mat4x4<f32>;
  view : mat4x4<f32>;
  position : vec3<f32>;
  time : f32;
  outputSize : vec2<f32>;
  zNear : f32;
  zFar : f32;
}

@binding(0) @group(0) var<uniform> camera : Camera;

struct ClusterLights {
  offset : u32;
  count : u32;
}

struct ClusterLightGroup {
  offset : u32;
  lights : array<ClusterLights, 27648>;
  indices : array<u32, 1769472>;
}

@binding(1) @group(0) var<storage, read> clusterLights : ClusterLightGroup;

struct Light {
  position : vec3<f32>;
  range : f32;
  color : vec3<f32>;
  intensity : f32;
}

struct GlobalLights {
  ambient : vec3<f32>;
  dirColor : vec3<f32>;
  dirIntensity : f32;
  dirDirection : vec3<f32>;
  lightCount : u32;
  lights : @stride(32) array<Light>;
}

@binding(2) @group(0) var<storage, read> globalLights : GlobalLights;

let tileCount = vec3(32u, 18u, 48u);

fn linearDepth(depthSample : f32) -> f32 {
  return ((camera.zFar * camera.zNear) / fma(depthSample, (camera.zNear - camera.zFar), camera.zFar));
}

fn getTile(fragCoord : vec4<f32>) -> vec3<u32> {
  let sliceScale = (f32(tileCount.z) / log2((camera.zFar / camera.zNear)));
  let sliceBias = -(((f32(tileCount.z) * log2(camera.zNear)) / log2((camera.zFar / camera.zNear))));
  let zTile = u32(max(((log2(linearDepth(fragCoord.z)) * sliceScale) + sliceBias), 0.0));
  return vec3(u32((fragCoord.x / (camera.outputSize.x / f32(tileCount.x)))), u32((fragCoord.y / (camera.outputSize.y / f32(tileCount.y)))), zTile);
}

fn getClusterIndex(fragCoord : vec4<f32>) -> u32 {
  let tile = getTile(fragCoord);
  return ((tile.x + (tile.y * tileCount.x)) + ((tile.z * tileCount.x) * tileCount.y));
}

@binding(3) @group(0) var defaultSampler : sampler;

@binding(4) @group(0) var shadowTexture : texture_depth_2d;

@binding(5) @group(0) var shadowSampler : sampler_comparison;

struct LightShadowTable {
  light : array<i32>;
}

@binding(6) @group(0) var<storage, read> lightShadowTable : LightShadowTable;

var<private> shadowSampleOffsets : array<vec2<f32>, 16> = array<vec2<f32>, 16>(vec2(-1.5, -1.5), vec2(-1.5, -0.5), vec2(-1.5, 0.5), vec2(-1.5, 1.5), vec2(-0.5, -1.5), vec2(-0.5, -0.5), vec2(-0.5, 0.5), vec2(-0.5, 1.5), vec2(0.5, -1.5), vec2(0.5, -0.5), vec2(0.5, 0.5), vec2(0.5, 1.5), vec2(1.5, -1.5), vec2(1.5, -0.5), vec2(1.5, 0.5), vec2(1.5, 1.5));

let shadowSampleCount = 16u;

struct ShadowProperties {
  viewport : vec4<f32>;
  viewProj : mat4x4<f32>;
}

struct LightShadows {
  properties : array<ShadowProperties>;
}

@binding(7) @group(0) var<storage, read> shadow : LightShadows;

fn dirLightVisibility(worldPos : vec3<f32>) -> f32 {
  let shadowIndex = lightShadowTable.light[0u];
  if ((shadowIndex == -1)) {
    return 1.0;
  }
  let viewport = shadow.properties[shadowIndex].viewport;
  let lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0));
  let shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5, -0.5)) + vec2(0.5, 0.5)), (lightPos.z / lightPos.w));
  let viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw)));
  let texelSize = (1.0 / vec2<f32>(textureDimensions(shadowTexture, 0)));
  let clampRect = vec4((viewport.xy - texelSize), ((viewport.xy + viewport.zw) + texelSize));
  var visibility = 0.0;
  for(var i = 0u; (i < shadowSampleCount); i = (i + 1u)) {
    visibility = (visibility + textureSampleCompareLevel(shadowTexture, shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.003)));
  }
  return (visibility / f32(shadowSampleCount));
}

fn getCubeFace(v : vec3<f32>) -> i32 {
  let vAbs = abs(v);
  if (((vAbs.z >= vAbs.x) && (vAbs.z >= vAbs.y))) {
    if ((v.z < 0.0)) {
      return 5;
    }
    return 4;
  }
  if ((vAbs.y >= vAbs.x)) {
    if ((v.y < 0.0)) {
      return 3;
    }
    return 2;
  }
  if ((v.x < 0.0)) {
    return 1;
  }
  return 0;
}

fn pointLightVisibility(lightIndex : u32, worldPos : vec3<f32>, pointToLight : vec3<f32>) -> f32 {
  var shadowIndex = lightShadowTable.light[(lightIndex + 1u)];
  if ((shadowIndex == -1)) {
    return 1.0;
  }
  shadowIndex = (shadowIndex + getCubeFace((pointToLight * -1.0)));
  let viewport = shadow.properties[shadowIndex].viewport;
  let lightPos = (shadow.properties[shadowIndex].viewProj * vec4(worldPos, 1.0));
  let shadowPos = vec3((((lightPos.xy / lightPos.w) * vec2(0.5, -0.5)) + vec2(0.5, 0.5)), (lightPos.z / lightPos.w));
  let viewportPos = vec2((viewport.xy + (shadowPos.xy * viewport.zw)));
  let texelSize = (1.0 / vec2<f32>(textureDimensions(shadowTexture, 0)));
  let clampRect = vec4(viewport.xy, (viewport.xy + viewport.zw));
  var visibility = 0.0;
  for(var i = 0u; (i < shadowSampleCount); i = (i + 1u)) {
    visibility = (visibility + textureSampleCompareLevel(shadowTexture, shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.01)));
  }
  return (visibility / f32(shadowSampleCount));
}

struct VertexOutput {
  @builtin(position)
  position : vec4<f32>;
  @location(0)
  worldPos : vec3<f32>;
  @location(1)
  view : vec3<f32>;
  @location(2)
  texcoord : vec2<f32>;
  @location(3)
  texcoord2 : vec2<f32>;
  @location(4)
  color : vec4<f32>;
  @location(5)
  instanceColor : vec4<f32>;
  @location(6)
  normal : vec3<f32>;
  @location(7)
  tangent : vec3<f32>;
  @location(8)
  bitangent : vec3<f32>;
}

struct Material {
  baseColorFactor : vec4<f32>;
  emissiveFactor : vec3<f32>;
  occlusionStrength : f32;
  metallicRoughnessFactor : vec2<f32>;
  alphaCutoff : f32;
}

@binding(8) @group(0) var<uniform> material : Material;

@binding(9) @group(0) var baseColorTexture : texture_2d<f32>;

@binding(10) @group(0) var baseColorSampler : sampler;

@binding(11) @group(0) var normalTexture : texture_2d<f32>;

@binding(12) @group(0) var normalSampler : sampler;

@binding(13) @group(0) var metallicRoughnessTexture : texture_2d<f32>;

@binding(14) @group(0) var metallicRoughnessSampler : sampler;

@binding(15) @group(0) var occlusionTexture : texture_2d<f32>;

@binding(16) @group(0) var occlusionSampler : sampler;

@binding(17) @group(0) var emissiveTexture : texture_2d<f32>;

@binding(18) @group(0) var emissiveSampler : sampler;

struct SurfaceInfo {
  baseColor : vec4<f32>;
  albedo : vec3<f32>;
  metallic : f32;
  roughness : f32;
  normal : vec3<f32>;
  f0 : vec3<f32>;
  ao : f32;
  emissive : vec3<f32>;
  v : vec3<f32>;
}

fn GetSurfaceInfo(input : VertexOutput) -> SurfaceInfo {
  var surface : SurfaceInfo;
  surface.v = normalize(input.view);
  let tbn = mat3x3(input.tangent, input.bitangent, input.normal);
  let normalMap = textureSample(normalTexture, normalSampler, input.texcoord).rgb;
  surface.normal = normalize((tbn * ((2.0 * normalMap) - vec3(1.0))));
  let baseColorMap = textureSample(baseColorTexture, baseColorSampler, input.texcoord);
  surface.baseColor = ((input.color * material.baseColorFactor) * baseColorMap);
  if ((surface.baseColor.a < material.alphaCutoff)) {
    discard;
  }
  surface.albedo = surface.baseColor.rgb;
  let metallicRoughnessMap = textureSample(metallicRoughnessTexture, metallicRoughnessSampler, input.texcoord);
  surface.metallic = (material.metallicRoughnessFactor.x * metallicRoughnessMap.b);
  surface.roughness = (material.metallicRoughnessFactor.y * metallicRoughnessMap.g);
  let dielectricSpec = vec3(0.039999999);
  surface.f0 = mix(dielectricSpec, surface.albedo, vec3(surface.metallic));
  let occlusionMap = textureSample(occlusionTexture, occlusionSampler, input.texcoord);
  surface.ao = (material.occlusionStrength * occlusionMap.r);
  let emissiveMap = textureSample(emissiveTexture, emissiveSampler, input.texcoord);
  surface.emissive = (material.emissiveFactor * emissiveMap.rgb);
  if ((input.instanceColor.a == 0.0)) {
    surface.albedo = (surface.albedo + input.instanceColor.rgb);
  } else {
    surface.albedo = (surface.albedo * input.instanceColor.rgb);
  }
  return surface;
}

let PI = 3.141592741;

let LightType_Point = 0u;

let LightType_Spot = 1u;

let LightType_Directional = 2u;

struct PuctualLight {
  lightType : u32;
  pointToLight : vec3<f32>;
  range : f32;
  color : vec3<f32>;
  intensity : f32;
}

fn FresnelSchlick(cosTheta : f32, F0 : vec3<f32>) -> vec3<f32> {
  return (F0 + ((vec3(1.0) - F0) * pow((1.0 - cosTheta), 5.0)));
}

fn DistributionGGX(N : vec3<f32>, H : vec3<f32>, roughness : f32) -> f32 {
  let a = (roughness * roughness);
  let a2 = (a * a);
  let NdotH = max(dot(N, H), 0.0);
  let NdotH2 = (NdotH * NdotH);
  let num = a2;
  let denom = ((NdotH2 * (a2 - 1.0)) + 1.0);
  return (num / ((PI * denom) * denom));
}

fn GeometrySchlickGGX(NdotV : f32, roughness : f32) -> f32 {
  let r = (roughness + 1.0);
  let k = ((r * r) / 8.0);
  let num = NdotV;
  let denom = ((NdotV * (1.0 - k)) + k);
  return (num / denom);
}

fn GeometrySmith(N : vec3<f32>, V : vec3<f32>, L : vec3<f32>, roughness : f32) -> f32 {
  let NdotV = max(dot(N, V), 0.0);
  let NdotL = max(dot(N, L), 0.0);
  let ggx2 = GeometrySchlickGGX(NdotV, roughness);
  let ggx1 = GeometrySchlickGGX(NdotL, roughness);
  return (ggx1 * ggx2);
}

fn lightAttenuation(light : PuctualLight) -> f32 {
  if ((light.lightType == LightType_Directional)) {
    return 1.0;
  }
  let distance = length(light.pointToLight);
  if ((light.range <= 0.0)) {
    return (1.0 / pow(distance, 2.0));
  }
  return (clamp((1.0 - pow((distance / light.range), 4.0)), 0.0, 1.0) / pow(distance, 2.0));
}

fn lightRadiance(light : PuctualLight, surface : SurfaceInfo) -> vec3<f32> {
  let L = normalize(light.pointToLight);
  let H = normalize((surface.v + L));
  let NDF = DistributionGGX(surface.normal, H, surface.roughness);
  let G = GeometrySmith(surface.normal, surface.v, L, surface.roughness);
  let F = FresnelSchlick(max(dot(H, surface.v), 0.0), surface.f0);
  let kD = ((vec3(1.0) - F) * (1.0 - surface.metallic));
  let NdotL = max(dot(surface.normal, L), 0.0);
  let numerator = ((NDF * G) * F);
  let denominator = max(((4.0 * max(dot(surface.normal, surface.v), 0.0)) * NdotL), 0.001);
  let specular = (numerator / vec3(denominator));
  let radiance = ((light.color * light.intensity) * lightAttenuation(light));
  return (((((kD * surface.albedo) / vec3(PI)) + specular) * radiance) * NdotL);
}

@binding(19) @group(0) var ssaoTexture : texture_2d<f32>;

struct FragmentOutput {
  @location(0)
  color : vec4<f32>;
  @location(1)
  emissive : vec4<f32>;
}

@stage(fragment)
fn fragmentMain(input : VertexOutput) -> FragmentOutput {
  let surface = GetSurfaceInfo(input);
  var Lo = vec3(0.0, 0.0, 0.0);
  if ((globalLights.dirIntensity > 0.0)) {
    var light : PuctualLight;
    light.lightType = LightType_Directional;
    light.pointToLight = globalLights.dirDirection;
    light.color = globalLights.dirColor;
    light.intensity = globalLights.dirIntensity;
    let lightVis = dirLightVisibility(input.worldPos);
    Lo = (Lo + (lightRadiance(light, surface) * lightVis));
  }
  let clusterIndex = getClusterIndex(input.position);
  let lightOffset = clusterLights.lights[clusterIndex].offset;
  let lightCount = clusterLights.lights[clusterIndex].count;
  for(var lightIndex = 0u; (lightIndex < lightCount); lightIndex = (lightIndex + 1u)) {
    let i = clusterLights.indices[(lightOffset + lightIndex)];
    var light : PuctualLight;
    light.lightType = LightType_Point;
    light.pointToLight = (globalLights.lights[i].position.xyz - input.worldPos);
    light.range = globalLights.lights[i].range;
    light.color = globalLights.lights[i].color;
    light.intensity = globalLights.lights[i].intensity;
    let lightVis = pointLightVisibility(i, input.worldPos, light.pointToLight);
    Lo = (Lo + (lightRadiance(light, surface) * lightVis));
  }
  let ssaoCoord = (input.position.xy / vec2<f32>(textureDimensions(ssaoTexture).xy));
  let ssaoFactor = textureSample(ssaoTexture, defaultSampler, ssaoCoord).r;
  let ambient = (((globalLights.ambient * surface.albedo) * surface.ao) * ssaoFactor);
  let color = linearTosRGB(((Lo + ambient) + surface.emissive));
  var out : FragmentOutput;
  out.color = vec4(color, surface.baseColor.a);
  out.emissive = vec4(surface.emissive, surface.baseColor.a);
  return out;
}
