How to compute LOD in pixel shader?

In my program, I need to compute the mipmap level for each vertex or each fragment manually. Is there any feasible way to compute it in vertex or pixel shader?

The sample codes from NVidia give the following method,
HPosition = mul(matModelViewProj, Obj.Position);
LOD = (HPosition.z/HPosition.w)*MaxMipmapLevel.

The resulting LOD ranges from 2.7~4.3, though I define mipmaps from Level 0 to level 6, given a 256 base texture. I think LOD should have values from 0~6 rather than 2.7~4.3.

Do I miss something in this process? Does anyone know another better approximation method to compute LOD? And I wonder where such computation takes place, in vertex shader or in pixel shader?

Thanks a lot!


For texture space LOD computations you need the partial derivatives of the texture coordinates with respect to x and y window coordinates. These partials are then used in the usual LOD calculations. These LOD calculations are performed by the rasterizer which connects the vertex units to the fragment units.

According to the sample code you provided, I assume you’re looking for model space LOD computation, because all it does is calculate the z-distance after mvp transformation and multiplying that with the maxmipmaplevel.
In theory hposition.z/hposition.w ranges from -1 to 1 in the visible view volume. So the computed LOD should lie within -maxmipmaplevel…maxmipmaplevel. This is useful if you have a number of instances of the same model with a different vertex count to achieve better performance by drawing less vertices if the model is far away from the camera. You could rescale the LOD-range by a simple multiply-add to get it in the desired range.