Search Unity

Single pass rendering - How do we display a gameObject with a different offset for each eye

Discussion in 'General Graphics' started by wirelessdreamer, May 27, 2019.

  1. wirelessdreamer

    wirelessdreamer

    Joined:
    Apr 13, 2016
    Posts:
    134
    Here is the problem I'm dealing with. I moved to single pass rendering, and now the reticle for my weapon shows up with a slight offset if you compare its location between eyes. I put in world space so it shows up to both eyes, to help with the fact that in the dominate eye, it is seen on the edge of the Fresnel lens

    when aiming at a target, if i look with the right eye, and left eye, keeping it aimed at the same object, it shows up in slightly different locations, so a lot of impacts are off by an inch or 2.

    I'm looking for either

    1. a correct solution, how do fix that offset so they actually render in the same location for both eyes

    or

    2. a way to render seperate objects for each eye, and i'll just make 2 reticles, and maually correct the offset to give a sharp reticle in the correct location.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
    A common solution for this is to actually place the reticle on the object you’re going to hit by raycasting forward and drawing the mesh there. You can have it draw in a late queue, scale it up based on distance, and use ZTest Always so it doesn’t clip through walls.

    The other solution is to not fix it at all. This is a problem that happens in the real world with real weapons that use something like a red dot / reflex sight. Generally you can only see this in one eye at a time due to the small scope size, but you still have to roughly line up the holographic dot with the weapon itself, so you have two points of reference to line up. That or switch to a laser sight ... which is basically the same thing as above where a dot shows up roughly where you’re going to hit.

    However if you really want to go back to having a reticle that is in the “same” spot in each eye, the trick to that is to position it in the shader. Put the reticle mesh someplace in front of the camera so it’s guaranteed to be seen, but ignore the model (object to world) matrix entirely. You’ll scale and position the mesh in view space via custom properties instead.

    float3 viewPos = v.vertex.xyz * _Scale + _Offset;
    o.pos = mul(UNITY_MATRIX_P, float4(viewPos, 1.0));

    If you’re using the built in quad mesh, this should “just work”. If you’re using a custom mesh, you may need to rotate the pivot and reimport, or play with that xyz component order.