#version 150
#extension GL_ARB_texture_gather : enable
/// BEGIN AUTOGENERATED HEADER
#define CONC(a,b) a##b

#define IF(c, t, e) CONC(IF_, c)(t, e)

#define IF_UNDEF(t, e) e
#define IF_0(t, e) t
#define IF_1(t, e) t
#define IF_2(t, e) t
#define IF_3(t, e) t
#define IF_4(t, e) t
#define IF_5(t, e) t
#define IF_6(t, e) t
#define IF_7(t, e) t
#define IF_8(t, e) t
#define IF_9(t, e) t
#define IF_10(t, e) t
#define IF_11(t, e) t
#define IF_12(t, e) t
#define IF_13(t, e) t
#define IF_14(t, e) t
#define IF_15(t, e) t
#define IF_16(t, e) t
// Workaround for intel HD:
#define IF_00(t, e) t
#ifdef GL_SPIRV
	#define LAYOUT_SAMPLER2(s, b) layout(set = s, binding = b)
	#define LAYOUT_SAMPLER(s, b) layout(set = s, binding = b)
	#define LAYOUT_UBO(s, b) layout(std140, set = s, binding = b)
	#define LAYOUT_PUSH_CONSTANT() layout(push_constant, std140)

	#define VERTEX_INPUT(loc, type, name, defaultValue) IF(loc, layout (location = loc) in type name, const type name = defaultValue)
		
	#define INPUT_MOD(loc, mod, type, name, defaultValue) IF(loc, layout (location = loc) mod in type name, const type name = defaultValue)
		
	#define INPUT(loc, type, name, defaultValue) IF(loc, layout (location = loc) in type name, const type name = defaultValue)

	#define OUTPUT(loc, type, name) IF(loc, layout (location = loc) out type name, type name)
	
	#define OUTPUT_MOD(loc, mod, type, name) IF(loc, layout (location = loc) mod out type name, type name)
	
	#define WINDING cw

	#define LOCATION(loc) layout(location = loc) 
#else
	#extension GL_ARB_separate_shader_objects : require
	#extension GL_ARB_explicit_attrib_location : require
	#extension GL_ARB_shading_language_420pack : require

#ifdef USE_SAMPLER2
	#define LAYOUT_SAMPLER2(s, b)
#else
	#define LAYOUT_SAMPLER2(s, b) layout(binding = b)
#endif

	#define LAYOUT_SAMPLER(s, b) layout(binding = b)
	#define LAYOUT_UBO(s, b) layout(std140, binding = b)
	#define LAYOUT_PUSH_CONSTANT() layout(std140, binding = 2)

	#define VERTEX_INPUT(loc, type, name, defaultValue) IF(loc, layout (location = loc) in type name, const type name = defaultValue)
		
	#define INPUT_MOD(loc, mod, type, name, defaultValue) mod in type name
		
	#define INPUT(loc, type, name, defaultValue) in type name

	#define OUTPUT(loc, type, name) out type name
	
	#define OUTPUT_MOD(loc, mod, type, name) mod out type name
	
	#define WINDING ccw

	#define LOCATION(loc)
#endif
/// END AUTOGENERATED HEADER

LAYOUT_SAMPLER(1, 26) uniform sampler2DArray detailColorArrayTex;
LAYOUT_SAMPLER(1, 27) uniform sampler2DArray detailNrmlArrayTex;
LAYOUT_SAMPLER(1, 28) uniform sampler2DArray detailGlossArrayTex;
LAYOUT_SAMPLER(1, 29) uniform sampler2DArray overlayArrayTex;

const float texpixel = 1.0/4096.0;

LAYOUT_UBO(1, 15) uniform DataBlock {
	vec4 data[255];
} u_dataBlock;

vec3 overlay(vec4 col0, vec3 col1);

vec3 transformNormal(vec3 normal) {
	return normal;
}

vec3 getLevelColor(vec3 pos, int iLevel, vec3 normal, 
		out vec2 nrml, out vec3 glossAoH, vec3 dposdx, vec3 dposdy) {
	vec3 doSizeoStrength = u_dataBlock.data[iLevel].xyz;

	if (doSizeoStrength.z > 1000) {
		float scale = doSizeoStrength.x;
		vec2 tiles = doSizeoStrength.yz;
		tiles.y -= 1001;
	
		pos.xy = pos.xy * scale * texpixel + 0.5*tiles.xy;
		dposdx = dposdx * scale * texpixel;
		dposdy = dposdy * scale * texpixel;
	
		nrml = vec2(0.5, 0.5);
		glossAoH = vec3 (0.0, 0.2, 0.0);
		int mapx = int(floor(pos.x));
		int mapy = int(floor(pos.y));
		
		int mapidx = mapx + int(tiles.x)*mapy;
		int idx = mapidx + iLevel;  // index for texture file
		if (mapidx >= 9) { // weird ordering bug: other textures in between on meglom. maps
			idx = idx+25; // 4 without mods, 25 with current mod list
		}
		// iLevel start 26
		
		vec2 subp = fract(pos.xy);	
		vec4 col0 = textureGrad(detailColorArrayTex, vec3(subp.xy, idx), dposdx.xy, dposdy.xy);

		// col0.rgb = vec3 (float(idx)/36.0, 0.0, 0.0);

		return col0.rgb;
	}
	else {
		pos = pos * doSizeoStrength.x;
		dposdx = dposdx * doSizeoStrength.x;
		dposdy = dposdy * doSizeoStrength.x;
	
		nrml = textureGrad(detailNrmlArrayTex, vec3(pos.xy, iLevel), dposdx.xy, dposdy.xy).rg;
		vec3 col = textureGrad(overlayArrayTex, vec3(pos.xy * doSizeoStrength.y, iLevel), dposdx.xy * doSizeoStrength.y, dposdy.xy * doSizeoStrength.y).rgb;
		vec4 col0 = textureGrad(detailColorArrayTex, vec3(pos.xy, iLevel), dposdx.xy, dposdy.xy);
		col0.a = doSizeoStrength.z;
		glossAoH = textureGrad(detailGlossArrayTex, vec3(pos.xy, iLevel), dposdx.xy, dposdy.xy).gba;
		glossAoH.z += u_dataBlock.data[iLevel].w;
		return overlay(col0, col.rgb);
	}	
}
