Mipmap level calculation using dFdx/dFdy


In a fragment shader I’m trying to calculate the mipmap level of a texture for the current fragment. To be more specific, my texture is not a real texture per se but a structure organized like a mipmap. I can easily see if my mipmap level is incorrect, eg. too “optimistic”.
My textures/structures are almost always highly anisotropic.

So far I’ve been using the following formulae, but it seems to be too “optimistic” - it is clear the lookup should be done lower down in the mipmap hierarchy, as I can see groups of fragments suddenly popping.

int calculateMip(vec2 texCoord) // both values between 0.0 and 1.0, inclusive
         float maxDerU = max( abs(dFdx(texCoord.x)), abs(dFdx(texCoord.y)) );
         float maxDerV = max( abs(dFdy(texCoord.x)), abs(dFdy(texCoord.y)) );
         float mip = log2(1.0 / max(maxDerU, maxDerV));
         return int(ceil(mip)); // returns the mipmap level

My calculation seems correct: I’m taking the maximum of all 4 partial derivatives, and make it a mipmap value. But this doesn’t work.

Do dFdx/dFdy return the derivatives between the current pixel and the pixel right to it/above it? Or the derivatives between the pixel left of the current pixel and right of it (resp. below and above)?


take a look at the OpenGL 4.2 spec chapter 3.9.11 equation 3.21. The mip map level is calculated based on the lengths of the derivative vectors:

mip_map_level(in vec2 texture_coordinate)
    // The OpenGL Graphics System: A Specification 4.2
    //  - chapter 3.9.11, equation 3.21

    vec2  dx_vtc        = dFdx(texture_coordinate);
    vec2  dy_vtc        = dFdy(texture_coordinate);
    float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));

    //return max(0.0, 0.5 * log2(delta_max_sqr) - 1.0); // == log2(sqrt(delta_max_sqr));
    return 0.5 * log2(delta_max_sqr); // == log2(sqrt(delta_max_sqr));

Sweet, I will give this a shot.

Thank you.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.