I have a Unity scene with OpenVR and Single Pass Stereo Rendering.
I need to do a fullscreen 3D masking effect in VR, based on reconstructed worldspace position from depth. I'm doing it using Graphics.Blit and a fullscreen quad.
The problem is once you have the reconstructed world pos, you can't just say "everything past
wpos.x==300 is black", because each eye will offset the mask and it appears like you're looking at it cross-eyed.
This is because the
wpos.x==300 method does not take into account the Interpupillary Distance (IPD) between the two vr "cameras" rendering the scene. According to the unity docs there's a
unity_StereoEyeIndex, and I used that to offset the eye ray for each eye by an arbitrary amount in camera space.
I can eyeball this offset using a float, but my question is how do you calculate it exactly? How do you make stereo masking shaders in VR?
I haven't yet reverse-engineered the problem fully, and am still waiting for a full answer. But I have fixed it for now by avoiding
Graphics.Blit() because it's too mysterious in VR, and instead used a sphere in the game world with a special material.
The shader I use is basically what @DMGregory did in this answer for his "Object in World" method. Note that you have to correct the depth sampling with this:
screenUV = UnityStereoTransformScreenSpaceTex(screenUV);
screenUV.y = 1.0f - screenUV.y;