vec3 normalGenerator(vec2 coord, vec2 midtex)
{
    float noiseVal = noise_standard(gl_FragCoord.xy);
    vec2 invTexSize = 1.0 / textureSize(texture, 0);

    vec2 deltaPos = invTexSize * noiseVal * 4.0;

#ifdef LOD_FIX
    vec3 colorSum = texture(texture, midtex).rgb;
    colorSum += texture(texture, midtex + vec2(deltaPos.x, 0.0)).rgb;
    colorSum += texture(texture, midtex - vec2(deltaPos.x, 0.0)).rgb;
    colorSum += texture(texture, midtex + vec2(0.0, deltaPos.y)).rgb;
    colorSum += texture(texture, midtex - vec2(0.0, deltaPos.y)).rgb;
    colorSum += texture(texture, midtex + deltaPos).rgb;
    colorSum += texture(texture, midtex - deltaPos).rgb;
    vec3 albedoAvg = colorSum / 6.0;
#else
    vec3 albedoAvg = (textureLod(texture, coord, 4.0).rgb + texture(texture, midtex).rgb) * 0.5;
#endif

    float baseLuma = luma(albedoAvg);

    float strength = 1.0;
    vec2 offsetScale = invTexSize * 0.1 * noiseVal;
    vec2 boundary = invTexSize * 8.0;

    vec2 sampleR = coord + vec2(offsetScale.x, 0.0);
    if (abs(sampleR.x - midtex.x) > boundary.x)
        sampleR.x = coord.x;
    float lumaR = luma(texture(texture, sampleR).rgb);

    vec2 sampleL = coord - vec2(offsetScale.x, 0.0);
    if (abs(sampleL.x - midtex.x) > boundary.x)
        sampleL.x = coord.x;
    float lumaL = luma(texture(texture, sampleL).rgb);

    vec2 sampleT = coord + vec2(0.0, offsetScale.y);
    if (abs(sampleT.y - midtex.y) > boundary.y)
        sampleT.y = coord.y;
    float lumaT = luma(texture(texture, sampleT).rgb);

    vec2 sampleB = coord - vec2(0.0, offsetScale.y);
    if (abs(sampleB.y - midtex.y) > boundary.y)
        sampleB.y = coord.y;
    float lumaB = luma(texture(texture, sampleB).rgb);

    float heightR = 1.0 - abs(lumaR - baseLuma);
    float heightL = 1.0 - abs(lumaL - baseLuma);
    float heightT = 1.0 - abs(lumaT - baseLuma);
    float heightB = 1.0 - abs(lumaB - baseLuma);

    float dx = (heightL - heightR) * strength;
    float dy = (heightB - heightT) * strength;

    vec3 n = normalize(vec3(dx, dy, 0.5));
    n = n * 0.5 + 0.5;
    n.z = 1.0;
    return n;
}