//Generated normals based on those from Emin#7309's Complementary Shaders. Tysm for allowing me to use them a YEAR prior to me actually implementing them in my shader
float getAlbedoDifference(float lAlbedo, vec2 offsetCoord) {
    float lNearbyAlbedo = length(texture2D(texture, offsetCoord).rgb);
    float albedoDifference = lAlbedo - lNearbyAlbedo;

    if (albedoDifference > 0.0) return clamp(max(albedoDifference - 0.05, 0.0), -NORMAL_THRESHOLD, NORMAL_THRESHOLD);
    else return clamp(min(albedoDifference + 0.05, 0.0), -NORMAL_THRESHOLD, NORMAL_THRESHOLD);
}

void getTerrainNormal(inout vec3 newNormal, vec3 albedo) {
    float lAlbedo = length(albedo);

    vec2 midCoord = texCoord - absMidCoordPos * signMidCoordPos;
    vec2 maxOffsetCoord = midCoord + absMidCoordPos;
    vec2 minOffsetCoord = midCoord - absMidCoordPos;
    vec2 resolutionOffset = (16.0 / atlasSize) / NORMAL_RESOLUTION;

	vec3 normalMap = vec3(0.0, 0.0, 1.0);

    vec2 offsetCoord = texCoord + vec2(resolutionOffset.x, 0.0);
    if (offsetCoord.x < maxOffsetCoord.x) normalMap.x += getAlbedoDifference(lAlbedo, offsetCoord);
            
    offsetCoord = texCoord + vec2(-resolutionOffset.x, 0.0);
    if (offsetCoord.x > minOffsetCoord.x) normalMap.x -= getAlbedoDifference(lAlbedo, offsetCoord);

    offsetCoord = texCoord + vec2(0.0, resolutionOffset.y);
    if (offsetCoord.y < maxOffsetCoord.y) normalMap.y += getAlbedoDifference(lAlbedo, offsetCoord);

    offsetCoord = texCoord + vec2(0.0, -resolutionOffset.y);
    if (offsetCoord.y > minOffsetCoord.y) normalMap.y -= getAlbedoDifference(lAlbedo, offsetCoord);

    normalMap.xy = clamp(normalMap.xy * NORMAL_STRENGTH, -0.5, 0.5);

    if (normalMap.xy != vec2(0.0)) {
        mat3 tbnMatrix = mat3(
            tangent.x, binormal.x, normal.x,
            tangent.y, binormal.y, normal.y,
            tangent.z, binormal.z, normal.z
        );

        newNormal = clamp(normalize(normalMap * tbnMatrix), -1.0, 1.0);
    }
}