layout(location = 0) out vec3 albedoData;
layout(location = 2) out vec4 colortex3Out;

/* DRAWBUFFERS:673 */

#include "/lib/Head/Common.inc"

#ifdef PARALLAX_SHADOW
	layout(location = 1) out vec4 colortex7Out;
#else
	layout(location = 1) out vec3 colortex7Out;
#endif



uniform sampler2D tex;
#ifdef MC_NORMAL_MAP
    uniform sampler2D normals;
#endif
#ifdef MC_SPECULAR_MAP
    uniform sampler2D specular;
#endif

uniform mat4 gbufferModelView;

uniform vec3 cameraPosition;
uniform vec3 worldLightVector;

in vec4 tint;
in vec2 texcoord;
in vec3 minecraftPos;
in vec3 viewPos;

in vec2 lightmap;

flat in mat3 tbnMatrix;

flat in uint materialIDs;

uniform int frameCounter;

#if defined PARALLAX || ANISOTROPIC_FILTER > 0
	in vec2 tileCoord;
	flat in vec2 tileOffset;
	flat in vec2 tileScale;

	vec2 OffsetCoord(in vec2 coord) { return tileOffset + tileScale * fract(coord); }
#endif

float InterleavedGradientNoiseTemporal(in vec2 coord) {
    return fract(52.9829189 * fract(0.06711056 * coord.x + 0.00583715 * coord.y + 0.00623715 * (frameCounter & 63)));
}

#ifdef PARALLAX
	#include "/lib/Surface/Parallax.glsl"
#endif

#if ANISOTROPIC_FILTER > 0
	vec3 AnisotropicFilter(in vec2 baseCoord, in mat2 texGrad) {
		mat2 J = inverse(texGrad);
		J = transpose(J) * J;

		float d = determinant(J);
		float t = J[0][0] + J[1][1];

		float D = sqrt(max0(t * t - 4.0 * d));
		float V = (t - D) * 0.5;
		float v = (t + D) * 0.5;
		float l = log2(inversesqrt(v));

		vec2 A = inversesqrt(V) * normalize(vec2(-J[0][1], J[0][0] - V));
		A /= tileScale;

		float c = 0.0;
		vec3 albedo = vec3(0.0);

		for (float i = 0.5 / ANISOTROPIC_FILTER - 0.5; i < 0.5; i += 1.0 / ANISOTROPIC_FILTER) {
			vec2 sampleCoord = OffsetCoord(baseCoord + i * A);

			vec4 albedoSample = textureLod(tex, sampleCoord, l);

			if (albedoSample.a > 1e-3) {
				albedo += albedoSample.rgb;
				++c;
			}
		}
		albedo /= max(c, 1.0);

		return albedo;
	}
#endif

#if defined IS_OVERWORLD
	uniform sampler2D noisetex;
	uniform sampler2D colortex7;

	uniform mat4 gbufferModelViewInverse;
	uniform float frameTimeCounter;
	uniform float wetnessCustom;

	#include "/lib/Surface/RainEffect.glsl"
#endif

// === DEBUG / OVERLAY MODE ===
#define LIGHT_OVERLAY 0 // [0 1] – 0 = выкл, 1 = включить оверлей света (X-метки как в моде)
#define CHUNK_OVERLAY 0 // [0 1] – 0 = выкл, 1 = включить оверлей чанков (границ)

// === Функция для определения деталей (полоски, гвозди, швы) ===
float detectDetails(vec3 albedo) {
    float brightness = dot(albedo.rgb, vec3(0.299, 0.587, 0.114));
    
    if (brightness < 0.25) return 1.0;
    if (brightness < 0.35) return 0.7;
    
    float contrast = abs(brightness - 0.5);
    if (contrast > 0.25 && brightness < 0.4) return 0.5;
    
    return 0.0;
}

// === Функция для определения чистоты меди ===
float detectCopperPurity(vec3 albedo) {
    float copperScore = albedo.r * (1.0 - albedo.b) * 0.7;
    float oxidizedScore = albedo.g * (1.0 - albedo.r) * 0.6;
    
    float total = copperScore + oxidizedScore + 0.001;
    return copperScore / total;
}

// === Функция для определения металлических частей ===
bool isMetalPart(vec3 albedo, uint matID) {
    float brightness = dot(albedo.rgb, vec3(0.299, 0.587, 0.114));
    
    if (matID == 2020u) {
        bool isDarkMetal = brightness < 0.35;
        bool isGoldenMetal = (albedo.r > 0.6 && albedo.g > 0.5 && albedo.b < 0.4);
        return isDarkMetal || isGoldenMetal;
    }
    
    if (matID == 2019u) {
        return brightness < 0.3;
    }
    
    return false;
}

// === Универсальная функция для настройки отражений по степени окисления ===
void applyOxidationLevel(inout float smoothness, inout float metalness, inout float fresnelStrength, 
                         inout vec3 metalTint, inout float reflectionSharpness, int oxidationLevel) {
    if (oxidationLevel == 0) { // Clean copper
        smoothness = 0.85;
        metalness = 0.92;
        fresnelStrength = 1.05;
        metalTint = vec3(1.0, 0.85, 0.75);
        reflectionSharpness = 0.95;
    } else if (oxidationLevel == 1) { // Exposed
        smoothness = 0.68;
        metalness = 0.85;
        fresnelStrength = 0.85;
        metalTint = vec3(0.95, 0.80, 0.70);
        reflectionSharpness = 0.70;
    } else if (oxidationLevel == 2) { // Weathered
        smoothness = 0.48;
        metalness = 0.70;
        fresnelStrength = 0.65;
        metalTint = vec3(0.85, 0.85, 0.75);
        reflectionSharpness = 0.45;
    } else { // Oxidized
        smoothness = 0.28;
        metalness = 0.50;
        fresnelStrength = 0.45;
        metalTint = vec3(0.80, 0.90, 0.85);
        reflectionSharpness = 0.22;
    }
}

void main() {
	vec3 normalData;
	vec4 albedo = tint;

	float dither = InterleavedGradientNoiseTemporal(gl_FragCoord.xy);

	vec2 texGradX = dFdx(texcoord);
	vec2 texGradY = dFdy(texcoord);
	mat2 texGrad = mat2(texGradX, texGradY);
	
	#ifdef PARALLAX
		#define ReadTexture(tex) textureGrad(tex, parallaxCoord, texGradX, texGradY)

		vec2 parallaxCoord = texcoord;

		#ifdef SMOOTH_PARALLAX
			float sampleHeight = BilinearHeightSample(texcoord);
		#else
			float sampleHeight = ReadTexture(normals).a;
		#endif

		vec3 offsetCoord;
		if (sampleHeight < 0.999) {
			vec3 tangentViewVector = normalize(viewPos.xyz) * tbnMatrix;

			offsetCoord = CalculateParallax(tangentViewVector, texGrad, dither);
			parallaxCoord = OffsetCoord(offsetCoord.xy);
		}

		#ifdef MC_NORMAL_MAP
			normalData = ReadTexture(normals).rgb;
			DecodeNormalTex(normalData);
		#else
			normalData = vec3(0.0, 0.0, 1.0);
		#endif

		if (sampleHeight < 0.999) {
			#ifdef PARALLAX_SHADOW
				if (offsetCoord.z < 0.9999) {
					vec3 viewLightVector = mat3(gbufferModelView) * worldLightVector;
					if (dot(tbnMatrix[2], viewLightVector) > 1e-3) {
						colortex7Out.w = CalculateParallaxShadow(viewLightVector * tbnMatrix, offsetCoord, texGrad, dither);
					}
					#ifdef PARALLAX_BASED_NORMAL
						vec2 shift = 1e-2 * tileScale;
						float rD = textureGrad(normals, OffsetCoord(offsetCoord.xy + vec2(shift.x, 0.0)), texGradX, texGradY).a;
						float lD = textureGrad(normals, OffsetCoord(offsetCoord.xy - vec2(shift.x, 0.0)), texGradX, texGradY).a;
						float uD = textureGrad(normals, OffsetCoord(offsetCoord.xy + vec2(0.0, shift.y)), texGradX, texGradY).a;
						float dD = textureGrad(normals, OffsetCoord(offsetCoord.xy - vec2(0.0, shift.y)), texGradX, texGradY).a;
						normalData = vec3((lD - rD), (dD - uD), step(abs(lD - rD) + abs(dD - uD), 1e-3));
					#endif
				}
			#endif
		}

		#if ANISOTROPIC_FILTER > 0
			if (materialIDs != 15u) {
				albedo.rgb *= AnisotropicFilter((parallaxCoord - tileOffset) / tileScale, texGrad);
				albedo.a *= ReadTexture(tex).a;
			} else
		#endif
	#else
		#define ReadTexture(tex) texture(tex, texcoord)

		#ifdef MC_NORMAL_MAP
			normalData = ReadTexture(normals).rgb;
        	DecodeNormalTex(normalData);
		#else
			normalData = vec3(0.0, 0.0, 1.0);
		#endif

		#if ANISOTROPIC_FILTER > 0
			if (materialIDs != 15u) {
				albedo.rgb *= AnisotropicFilter(tileCoord, texGrad);
				albedo.a *= ReadTexture(tex).a;
			} else
		#endif
	#endif
	{ albedo *= ReadTexture(tex); }

	if (albedo.a < 0.1) { discard; return; }

	#ifdef WHITE_WORLD
		albedo.rgb = vec3(1.0);
	#endif

	#ifdef MC_SPECULAR_MAP
		vec4 specularData = ReadTexture(specular);
	#else
		vec4 specularData = vec4(0.0);
	#endif

	// === СИСТЕМА ОТРАЖЕНИЙ ===
	bool isMetalBlock = false;
	float smoothness = 0.0;
	float metalness = 0.04;
	float fresnelStrength = 1.0;
	vec3 metalTint = vec3(1.0);
	float reflectionSharpness = 1.0;
	
	float detailMask = detectDetails(albedo.rgb);
	
	// === ЖЕЛЕЗНЫЙ БЛОК И ДВЕРЬ (2010, 2022) ===
	if (materialIDs == 2010u || materialIDs == 2022u) {
		isMetalBlock = true;
		smoothness = 0.75;
		metalness = 0.95;
		fresnelStrength = 1.0;
		metalTint = vec3(0.95, 0.95, 1.0);
		reflectionSharpness = 0.85;
		
		smoothness = mix(smoothness, smoothness * 0.35, detailMask);
	}
	
	// === ЖЕЛЕЗНЫЙ ЛЮК (2023) ===
	else if (materialIDs == 2023u) {
		isMetalBlock = true;
		smoothness = 0.72;
		metalness = 0.93;
		fresnelStrength = 0.95;
		metalTint = vec3(0.95, 0.95, 1.0);
		reflectionSharpness = 0.82;
		
		smoothness = mix(smoothness, smoothness * 0.35, detailMask);
	}
	
	// === ЗОЛОТОЙ БЛОК (2011) ===
	else if (materialIDs == 2011u) {
		isMetalBlock = true;
		smoothness = 0.70;
		metalness = 0.98;
		fresnelStrength = 1.1;
		metalTint = vec3(1.0, 0.95, 0.85);
		reflectionSharpness = 0.80;
		
		smoothness = mix(smoothness, smoothness * 0.45, detailMask);
	}

	
    else if (materialIDs == 2015u) {


		isMetalBlock = true;
		smoothness = 0.85;
		metalness = 0.55;
		fresnelStrength = 1.0;
		metalTint = vec3(0.05, 0.05, 0.05);
		reflectionSharpness = 0.85;
		
		smoothness = mix(smoothness, smoothness * 0.5, detailMask);






    }


		else if (materialIDs == 2014u) {
		isMetalBlock = true;
		smoothness = 0.95;
		metalness = 0.70;
		fresnelStrength = 1.30;
		metalTint = vec3(0.05, 0.05, 0.05);
		reflectionSharpness = 0.85;
		
		smoothness = mix(smoothness, smoothness * 0.5, detailMask);
	}
	

		else if (materialIDs == 2021u) {
		isMetalBlock = true;
		smoothness = 0.99;
		metalness = 0.75;
		fresnelStrength = 1.30;
		metalTint = vec3(0.05, 0.05, 0.05);
		reflectionSharpness = 1.85;
		
		smoothness = mix(smoothness, smoothness * 0.5, detailMask);
	}
	
	
	// === МЕДНЫЕ БЛОКИ (2012-2015) ===
	else if (materialIDs >= 2012u && materialIDs <= 2013u) {
		isMetalBlock = true;
		int oxidationLevel = int(materialIDs - 2012u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.35, detailMask);
	}
	
	// === МЕДНЫЕ ДВЕРИ (2024-2031) ===
	else if (materialIDs >= 2024u && materialIDs <= 2031u) {
		isMetalBlock = true;
		int oxidationLevel = int((materialIDs - 2024u) / 2u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		smoothness *= 0.92;
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.30, detailMask);
	}
	
	// === МЕДНЫЕ ЛЮКИ (2032-2039) ===
	else if (materialIDs >= 2032u && materialIDs <= 2039u) {
		isMetalBlock = true;
		int oxidationLevel = int((materialIDs - 2032u) / 2u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		smoothness *= 0.88;
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.30, detailMask);
	}
	
	// === МЕДНЫЕ РЕШЁТКИ (2040-2047) ===
	else if (materialIDs >= 2040u && materialIDs <= 2047u) {
		isMetalBlock = true;
		int oxidationLevel = int((materialIDs - 2040u) / 2u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		smoothness *= 0.85;
		metalness *= 0.90;
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.25, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.25, detailMask);
	}
	
	// === РЕЗНАЯ МЕДЬ (2048-2055) ===
	else if (materialIDs >= 2048u && materialIDs <= 2055u) {
		isMetalBlock = true;
		int oxidationLevel = int((materialIDs - 2048u) / 2u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		smoothness *= 0.80;
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.25, smoothness, purity);
		
		detailMask = max(detailMask, 0.4);
		smoothness = mix(smoothness, smoothness * 0.25, detailMask);
	}
	
	// === ГРОМООТВОД (2064) ===
	else if (materialIDs == 2064u) {
		isMetalBlock = true;
		smoothness = 0.82;
		metalness = 0.90;
		fresnelStrength = 1.0;
		metalTint = vec3(1.0, 0.85, 0.75);
		reflectionSharpness = 0.88;
		
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.30, detailMask);
	}
	
	// === OBSIDIAN (2016) ===
	else if (materialIDs == 2016u) {
		isMetalBlock = true;
		smoothness = 0.78;
		metalness = 0.12;
		fresnelStrength = 0.85;
		metalTint = vec3(0.85, 0.85, 0.95);
		reflectionSharpness = 0.65;
	}
	
	// === QUARTZ (2017) ===
	else if (materialIDs == 2017u) {
		isMetalBlock = true;
		smoothness = 0.65;
		metalness = 0.08;
		fresnelStrength = 0.70;
		metalTint = vec3(1.0, 1.0, 1.0);
		reflectionSharpness = 0.60;
		smoothness = mix(smoothness, smoothness * 0.5, detailMask);
	}
	
	// === COPPER CHEST (2018) ===
	else if (materialIDs == 2018u) {
		isMetalBlock = true;
		smoothness = 0.78;
		metalness = 0.88;
		fresnelStrength = 0.95;
		metalTint = vec3(1.0, 0.85, 0.75);
		reflectionSharpness = 0.90;
		
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.35, detailMask);
	}
	
	// === BARREL (2019) ===
	else if (materialIDs == 2019u) {
		if (isMetalPart(albedo.rgb, materialIDs)) {
			isMetalBlock = true;
			smoothness = 0.58;
			metalness = 0.75;
			fresnelStrength = 0.8;
			metalTint = vec3(0.9, 0.9, 0.9);
			reflectionSharpness = 0.70;
			smoothness = mix(smoothness, smoothness * 0.4, detailMask);
		}
	}
	
	// === CHEST (2020) ===
	else if (materialIDs == 2020u) {
		if (isMetalPart(albedo.rgb, materialIDs)) {
			isMetalBlock = true;
			smoothness = 0.68;
			metalness = 0.80;
			fresnelStrength = 0.88;
			metalTint = vec3(0.95, 0.90, 0.85);
			reflectionSharpness = 0.75;
			smoothness = mix(smoothness, smoothness * 0.45, detailMask);
		}
	}
	
	// === COPPER LANTERNS (60-67) ===
	else if (materialIDs >= 60u && materialIDs <= 67u) {
		isMetalBlock = true;
		int oxidationLevel = int((materialIDs - 60u) / 2u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		smoothness *= 0.94;
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.35, detailMask);
	}
	
	// === COPPER BULBS ON (80-87) ===
	else if (materialIDs >= 80u && materialIDs <= 87u) {
		isMetalBlock = true;
		int oxidationLevel = int((materialIDs - 80u) / 2u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		smoothness *= 0.88;
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.35, detailMask);
	}
	
	// === COPPER BULBS OFF (88-95) ===
	else if (materialIDs >= 88u && materialIDs <= 95u) {
		isMetalBlock = true;
		int oxidationLevel = int((materialIDs - 88u) / 2u);
		applyOxidationLevel(smoothness, metalness, fresnelStrength, metalTint, reflectionSharpness, oxidationLevel);
		
		smoothness *= 0.86;
		float purity = detectCopperPurity(albedo.rgb);
		smoothness = mix(smoothness * 0.3, smoothness, purity);
		smoothness = mix(smoothness, smoothness * 0.35, detailMask);
	}

    // === Старые materialIDs ===
    if (materialIDs == 9u || materialIDs == 59u) {
        if (materialIDs == 9u && albedo.r > 0.6 && albedo.g > 0.6 && albedo.b > 0.6) {
            specularData.r = 0.9; specularData.g = 0.2; specularData.b = 0.0;
        } else if (materialIDs == 59u && albedo.r > albedo.g * 1.2 && albedo.r > albedo.b * 1.5) {
            specularData.r = 0.7; specularData.g = 0.3; specularData.b = 0.0;
        } else if (materialIDs == 59u && albedo.b > albedo.r * 1.1 && albedo.b > albedo.g * 1.1) {
            specularData.r = 0.95; specularData.g = 0.1; specularData.b = 0.0;
            albedo.rgb *= vec3(0.8, 0.9, 1.0);
        }
    }

	// === МЕЧ (15) ===
	if (materialIDs == 15u) {
		specularData.r = 0.95;
		specularData.g = 1.0;
		specularData.b = 0.0;
		specularData.a = 0.0;
		albedo.rgb = mix(albedo.rgb, albedo.rgb * vec3(0.9, 0.95, 1.0), 0.3);
	}
	
	// === Применяем эффекты для металлических блоков ===
	if (isMetalBlock) {
		smoothness *= reflectionSharpness;
		
		specularData.r = smoothness;
		specularData.g = metalness;
		specularData.b = 0.0;
		specularData.a = 0.0;
		
		albedo.rgb = mix(albedo.rgb, albedo.rgb * metalTint, 0.35);
		albedo.rgb = pow(albedo.rgb, vec3(0.90));
		
		vec3 viewDir = normalize(viewPos.xyz);
		float fresnel = pow(1.0 - abs(dot(tbnMatrix[2], viewDir)), 2.5);
		
		vec3 fresnelColor = vec3(0.15, 0.18, 0.25);
		if (materialIDs == 2011u) fresnelColor = vec3(0.25, 0.22, 0.15);
		else if (materialIDs >= 2012u && materialIDs <= 2055u) fresnelColor = vec3(0.20, 0.15, 0.12);
		else if (materialIDs == 2016u) fresnelColor = vec3(0.12, 0.12, 0.20);
		else if (materialIDs == 2064u) fresnelColor = vec3(0.22, 0.17, 0.13);
		
		fresnel *= mix(0.4, 1.0, reflectionSharpness);
		albedo.rgb += fresnel * fresnelColor * fresnelStrength * (1.0 - detailMask * 0.5);
	}

	#if defined IS_OVERWORLD
		if (wetnessCustom > 1e-2) {
    		float noise = GetRainWetness(minecraftPos.xz - minecraftPos.y);
			noise *= remap(0.5, 0.9, (mat3(gbufferModelViewInverse) * tbnMatrix[2]).y);
			noise *= saturate(lightmap.y * 10.0 - 9.0);
    		float wetFact = smoothstep(0.54, 0.62, noise);

			#ifdef RAIN_SPLASH_EFFECT
				normalData = mix(normalData.xyz, vec3(GetRainNormal(minecraftPos), 1.0), wetFact * 0.5);
			#else
				normalData = mix(normalData.xyz, vec3(0.0, 0.0, 1.0), wetFact);
			#endif

    		wetFact = sqr(remap(0.35, 0.57, noise));

			#ifdef FORCE_WET_EFFECT
				if (!isMetalBlock) {
					specularData.r = mix(specularData.r, 1.0, wetFact);
					specularData.g = max(specularData.g, 0.04 * wetFact);
					specularData.rg += (dither - 0.5) * rcp(255.0);
				}
			#endif

			vec3 wetAlbedo = ColorSaturation(albedo.rgb, 0.75) * 0.85;
			#ifdef POROSITY
				float porosity = specularData.b > 64.5 / 255.0 ? 0.0 : remap(specularData.b, 0.0, 64.0 / 255.0) * 0.7;
				wetAlbedo *= oneMinus(porosity) / oneMinus(porosity * wetAlbedo);
			#endif
			if (!isMetalBlock) {
				albedo.rgb = mix(albedo.rgb, wetAlbedo, sqr(remap(0.3, 0.56, noise)));
			}
		}
	#endif

	#if TEXTURE_FORMAT == 0 && defined MC_SPECULAR_MAP
		#if SUBSERFACE_SCATTERING_MODE == 1
			if (materialIDs == 6u) specularData.b = max(0.45, specularData.b);
			if (materialIDs == 7u || materialIDs == 10u) specularData.b = max(0.7, specularData.b);
		#elif SUBSERFACE_SCATTERING_MODE == 0
			if (materialIDs == 6u) specularData.b = 0.45;
			if (materialIDs == 7u || materialIDs == 10u) specularData.b = 0.7;
		#endif
	#elif SUBSERFACE_SCATTERING_MODE < 2
		specularData.a = 0.0;
		if (materialIDs == 6u) specularData.a = 0.45;
		if (materialIDs == 7u || materialIDs == 10u) specularData.a = 0.7;
	#endif

	normalData = normalize(tbnMatrix * normalData);

	albedoData = albedo.rgb;

    // === OVERLAYS LIKE IN MOD ===
    #if LIGHT_OVERLAY == 1
        float blockLight = lightmap.x;
        float skyLight = lightmap.y;
        if (blockLight < 1.0 / 15.0) {
            vec2 uv = fract(minecraftPos.xz);
            float line1 = abs(uv.x - uv.y);
            float line2 = abs(uv.x + uv.y - 1.0);
            float thickness = 0.1;
            if (min(line1, line2) < thickness) {
                vec3 maskColor = (skyLight < 0.5 ? vec3(1.0, 0.0, 0.0) : vec3(1.0, 1.0, 0.0));
                float fade = 0.8;
                albedoData = mix(albedoData, maskColor, fade);
            }
        }
    #endif

    #if CHUNK_OVERLAY == 1
        float modX = mod(minecraftPos.x, 16.0);
        float modZ = mod(minecraftPos.z, 16.0);
        bool borderX = (modX < 0.1 || modX > 15.9);
        bool borderZ = (modZ < 0.1 || modZ > 15.9);
        if (borderX || borderZ) {
            vec3 maskColor = vec3(1.0, 0.0, 0.0);
            float fade = 0.5;
            albedoData = mix(albedoData, maskColor, fade);
        }
    #endif

	colortex7Out.xy = lightmap + (dither - 0.5) * rcp(255.0);
	colortex7Out.z = float(materialIDs + 0.1) * rcp(255.0);

	colortex3Out.xy = EncodeNormal(normalData);
	colortex3Out.z = PackUnorm2x8(specularData.rg);
	colortex3Out.w = PackUnorm2x8(specularData.ba);
}