Search code examples
openglprojectionperspectiveorthographic

How to draw ortho axes for object in perspective projection using modern OpenGL?


I have 3D scene with perspective projection. Also I can select an object on the scene. I need to draw axes for selected object. The problem is the axes don't save their size in perspective projection. If object is far from the eye (camera), axes is going be small too.

How to draw axes with the same size regardless of the position of the eye (camera)?


Solution

  • There are two ways to achieve this:

    Shader only approach

    When looking at the perspective projection, the size change according to depth is caused by the perspective divide (dividing all components by w). If you want to prevent this from happening, you can multiply the x and y coordinate of the projected vertices with the w-coordinate which will cancel out the perspective divide. It's a bit tricky to do because the correction before all other transformations, but something along this line should work for the general case:

    vec4 ndc = MVP * vec4(pos, 1);
    float sz = ndc.w;
    
    gl_Position= MVP * vec4(pos.xy * sz, pos.z, 1);
    

    Drawback: Needs a specialized shader

    CPU approach

    The other option is to render the axis with a orthographic projection, while calculating the location where it has to be placed on the CPU.

    This can, for example, be done by projection the target location with the perspective projection, perform the perspective divide. The resulting x,y components give the location in screen-space where the axis have to be placed.

    Now use this position to render the axis with orthographic projection which will maintain the sizes no matter how far away the axis are.

    Drawbacks: With this approach depth values might not be compatible with the perspective projected part of the scene.