Search Unity

Render different texture for each eye with single-pass pipeline?

Discussion in 'AR/VR (XR) Discussion' started by JoeStrout, Aug 24, 2018.

  1. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I just need to render an unlit transparent quad, but with a different texture for each eye.

    I suspect this is possible with a custom shader. Does anybody have such a beast lying around? Or even know whether it is possible?

    (I'm targeting Oculus Go, if it matters.)
     
  2. ad_lucem

    ad_lucem

    Joined:
    Mar 12, 2015
    Posts:
    3
    Hi,
    You need to look here : https://docs.unity3d.com/Manual/SinglePassStereoRendering.html

    You can just check the unity_StereoEyeIndex variable. unity_StereoEyeIndex is exposed in Shaders, so eye-dependent calculations can be performed. The value of unity_StereoEyeIndex is 0 for rendering of the left eye, and 1 for rendering of the right eye.

    This shader should work for unlit objects :

    Code (CSharp):
    1. Shader "Custom/Unlit/StereoTwoTextures"
    2. {
    3.     Properties
    4.     {
    5.         _LeftTex ("Left texture", 2D) = "white" {}
    6.         _RightTex ("Right texture", 2D) = "white" {}
    7.     }
    8.     SubShader
    9.     {
    10.         Tags { "RenderType"="Opaque" }
    11.         LOD 100
    12.  
    13.         Pass
    14.         {
    15.             CGPROGRAM
    16.             #pragma vertex vert
    17.             #pragma fragment frag
    18.             // make fog work
    19.             #pragma multi_compile_fog
    20.        
    21.             #include "UnityCG.cginc"
    22.  
    23.             struct appdata
    24.             {
    25.                 float4 vertex : POSITION;
    26.                 float2 uv : TEXCOORD0;
    27.             };
    28.  
    29.             struct v2f
    30.             {
    31.                 float2 uv : TEXCOORD0;
    32.                 float2 uv1 : TEXCOORD1;
    33.                 UNITY_FOG_COORDS(1)
    34.                 float4 vertex : SV_POSITION;
    35.             };
    36.  
    37.             sampler2D _LeftTex;
    38.             float4 _LeftTex_ST;
    39.  
    40.             sampler2D _RightTex;
    41.             float4 _RightTex_ST;
    42.                    
    43.             v2f vert (appdata v)
    44.             {
    45.                 v2f o;
    46.                 o.vertex = UnityObjectToClipPos(v.vertex);
    47.                 o.uv = TRANSFORM_TEX(v.uv, _LeftTex);
    48.                 o.uv1 = TRANSFORM_TEX(v.uv, _RightTex);
    49.                 UNITY_TRANSFER_FOG(o,o.vertex);
    50.                 return o;
    51.             }
    52.        
    53.             fixed4 frag (v2f i) : SV_Target
    54.             {
    55.                 // sample the texture
    56.                 fixed4 col;
    57.                 fixed4 l = tex2D(_LeftTex, i.uv);
    58.                 fixed4 r = tex2D(_RightTex, i.uv1);
    59.  
    60.                 col = r * unity_StereoEyeIndex + l * (1 - unity_StereoEyeIndex);
    61.  
    62.                 // apply fog
    63.                 UNITY_APPLY_FOG(i.fogCoord, col);
    64.                 return col;
    65.             }
    66.             ENDCG
    67.         }
    68.     }
    69. }
    70.  
     
    Last edited: Aug 31, 2018
    Rispat-Momit and JoeStrout like this.
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Thank you, that looks like just what I need! To avoid the branch, could we change lines 60-69 to something like:

    Code (csharp):
    1.     col = r * unity_StereoEyeIndex + l * (1 - unity_StereoEyeIndex);
    ?
     
    ad_lucem likes this.
  4. ad_lucem

    ad_lucem

    Joined:
    Mar 12, 2015
    Posts:
    3
    Indeed, fixed it ;)
     
    JoeStrout likes this.
  5. Rispat-Momit

    Rispat-Momit

    Joined:
    Feb 14, 2013
    Posts:
    266
    Hi there! Unfortunately, I can see the texture only through the Left eye. The right eye shows nothing. Any ideas on how to fix this?
     
  6. homoinanis

    homoinanis

    Joined:
    Sep 29, 2020
    Posts:
    7
    I have searched a lot on the internet. I can save you time. One day as of this post Unity offers absolutely nothing to get a single render texture with stereoscopic view using Single Instance.

    But of course, there is the issue that if you want to make a relatively complex game Single Instance is practically mandatory.

    The only solution I have found is also quite simple: use two cameras for each of the eyes of the HMD viewer. So, for each stereoscopic texture that we want, for example a portal, we will have to create two cameras that will track the position of the eyes in a relative way, recording the texture in two render textures that we can assign to each of the textures of a shader that unify in a single vision.
     
    MagiJedi likes this.
  7. howtopoz

    howtopoz

    Joined:
    Oct 18, 2017
    Posts:
    8
    Are you able to make unity render two cameras in headset? I've tested and each time the second camera in the hierarchy is just static or won't load/hangs on unity loading screen.
     
  8. KayH

    KayH

    Joined:
    Jan 6, 2017
    Posts:
    110
    This still works if you get the value in the vertex shader. See this post:
     
    Rispat-Momit likes this.