// Complementary-style generated normals
void generateNormals(inout vec3 newNormal, vec3 albedo, vec3 viewPos, in int mat) {
    if (mat == 30000) {
        // Improved normal generation for grass block using proper atlas bounds
        const float normalClamp = 0.35;
        const float packSizeGN = 16.0;

        float viewDistance = clamp(length(viewPos) * 0.01, 0.0, 1.0) * 0.10;
        float disableNormal = viewDistance * 10.0;

        if (disableNormal < 0.75) {
            float normalMult = (1.0 - disableNormal) * 1.2;

            vec2 absMidCoordPos2 = absMidCoordPos * 2.0;
            #ifndef SAFE_GENERATED_NORMALS
                vec2 offsetR = 16.0 / atlasSize;
            #else
                vec2 offsetR = max(absMidCoordPos2.x, absMidCoordPos2.y) * vec2(float(atlasSize.y) / float(atlasSize.x), 1.0);
            #endif
            offsetR /= packSizeGN;

            vec2 midCoord = texCoord - absMidCoordPos * signMidCoordPos;
            vec2 maxOffsetCoord = midCoord + absMidCoordPos;
            vec2 minOffsetCoord = midCoord - absMidCoordPos;

            float lOriginalAlbedo = dot(albedo, vec3(0.299, 0.587, 0.114));
            float lUp    = dot(texture2D(texture, clamp(texCoord + vec2(0.0,  offsetR.y), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));
            float lDown  = dot(texture2D(texture, clamp(texCoord + vec2(0.0, -offsetR.y), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));
            float lRight = dot(texture2D(texture, clamp(texCoord + vec2( offsetR.x, 0.0), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));
            float lLeft  = dot(texture2D(texture, clamp(texCoord + vec2(-offsetR.x, 0.0), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));

            float dx = (lRight - lLeft);
            float dy = (lUp - lDown);

            vec3 normalMap = vec3(dx, dy, 1.0 / normalMult);
            normalMap = normalize(normalMap);

            mat3 tbnMatrix = mat3(
                tangent.x, binormal.x, normal.x,
                tangent.y, binormal.y, normal.y,
                tangent.z, binormal.z, normal.z
            );
            newNormal = clamp(normalMap * tbnMatrix, -1.0, 1.0);
        }
        return;
    }
    // Apply the same improved normal generation logic to all other blocks
    const float normalClamp = 0.35;
    const float packSizeGN = 16.0;

    float viewDistance = clamp(length(viewPos) * 0.01, 0.0, 1.0) * 0.10;
    float disableNormal = float(mat == 30000) * clamp(dot(newNormal, upVec), 0.0, 1.0) + viewDistance;

    if (disableNormal < 0.75) {
        float normalMult = max(1.0 - (disableNormal / 0.75), 0.0) * 1.2 * NORMAL_STRENGTH;

        vec2 absMidCoordPos2 = absMidCoordPos * 2.0;
        #ifndef SAFE_GENERATED_NORMALS
            vec2 offsetR = 16.0 / atlasSize;
        #else
            vec2 offsetR = max(absMidCoordPos2.x, absMidCoordPos2.y) * vec2(float(atlasSize.y) / float(atlasSize.x), 1.0);
        #endif
        offsetR /= packSizeGN;

        vec2 midCoord = texCoord - absMidCoordPos * signMidCoordPos;
        vec2 maxOffsetCoord = midCoord + absMidCoordPos;
        vec2 minOffsetCoord = midCoord - absMidCoordPos;

        float lOriginalAlbedo = dot(albedo, vec3(0.299, 0.587, 0.114));
        float lUp    = dot(texture2D(texture, clamp(texCoord + vec2(0.0,  offsetR.y), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));
        float lDown  = dot(texture2D(texture, clamp(texCoord + vec2(0.0, -offsetR.y), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));
        float lRight = dot(texture2D(texture, clamp(texCoord + vec2( offsetR.x, 0.0), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));
        float lLeft  = dot(texture2D(texture, clamp(texCoord + vec2(-offsetR.x, 0.0), minOffsetCoord, maxOffsetCoord)).rgb, vec3(0.299, 0.587, 0.114));

        float dx = (lRight - lLeft);
        float dy = (lUp - lDown);

        vec3 normalMap = vec3(dx, dy, 1.0 / normalMult);
        normalMap = normalize(normalMap);

        mat3 tbnMatrix = mat3(
            tangent.x, binormal.x, normal.x,
            tangent.y, binormal.y, normal.y,
            tangent.z, binormal.z, normal.z
        );
        newNormal = clamp(normalMap * tbnMatrix, -1.0, 1.0);
    }
}

