Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

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,835
    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,835
    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:
    261
    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.