The main reason is that usually your bright positions will not be provided in the model space, but in the global space. However, for lighting to work efficiently, all calculations must be performed in a common space. In your normal transformation chain, the local coordinates of the model are transformed by the model view matrix directly into the view space
p_view = MV · p_local
Since you usually only have one model matrix, it would be cumbersome to divide this stem into something like
p_world = M · p_local p_view = V · p_world
To do this, you need MV to be separate.
Since projection transformation traditionally takes place as a separate step, the viewing space is the natural “common bottom ground” on which the illumination calculation is calculated. It just includes a conversion that converts your light positions from the world to view the space, and since light positions are not very complicated, this is done on the CPU and pre-reformed light positions specified as a shader.
Please note: there is nothing stopping you from doing light calculations in world space or modeling local space. It just correctly converts light positions.
source share