Search Unity

Question StereoScopic Skybox

Discussion in 'VR' started by jthiess, Dec 6, 2022.

  1. jthiess

    jthiess

    Joined:
    Nov 5, 2018
    Posts:
    31
    Hello!
    I have 360 stereoscopic images and am building a unity application that will play them on a 3D curved video wall. The wall itself sort of functions like a HMD and requires special scripts to properly play the unity app as upon launch the wall creates 3 cameras to cover the large surface area. These specialized scripts require Unity 2018.4.12f1 (this backstory is probably very confusing... i apologize!) The developer of the wall has given me the following script that helps map the 3D image to left and right eyes:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class StereoCameraController : MonoBehaviour
    6. {
    7.     // Start is called before the first frame update
    8.     void Start()
    9.     {
    10.         Camera[] cameras = Camera.allCameras;
    11.         for(int i = 0; i < Camera.allCamerasCount; i++)
    12.         {
    13.             Camera cam = Camera.allCameras[i];
    14.             if(i%2 == 0)
    15.                 cam.cullingMask &= ~(1 << LayerMask.NameToLayer("right"));
    16.             else
    17.                 cam.cullingMask &= ~(1 << LayerMask.NameToLayer("left"));
    18.         }
    19.     }
    20. }
    21.  
    This script works great 360 Images mapped onto an inverted sphere, however, these spheres always has a bad zenith/nadir seam, so I want to try with a skybox instead. The tricky part is getting the above code to work with the skybox. I have been using the following script to create a stereoscopic skybox shader (below), but I need to find a way to apply a layermask (left/right) to the images the shader produces.

    Code (CSharp):
    1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    2.  
    3. Shader "Skybox/CubemapStereo" {
    4.     Properties{
    5.         _Tint("Tint Color", Color) = (.5, .5, .5, .5)
    6.         [Gamma] _Exposure("Exposure", Range(0, 8)) = 1.0
    7.         _Rotation("Rotation", Range(0, 360)) = 0
    8.         [NoScaleOffset] _TexLeft("Cubemap   (HDR)", Cube) = "grey" {}
    9.             [NoScaleOffset] _TexRight("Cubemap   (HDR)", Cube) = "grey" {}
    10.     }
    11.  
    12.         SubShader{
    13.             Tags { "Queue" = "Background" "RenderType" = "Background" "PreviewType" = "Skybox" }
    14.             Cull Off ZWrite Off
    15.  
    16.             Pass {
    17.  
    18.                 CGPROGRAM
    19.                 #pragma vertex vert
    20.                 #pragma fragment frag
    21.                 #pragma target 2.0
    22.  
    23.                 #include "UnityCG.cginc"
    24.  
    25.                 samplerCUBE _TexLeft;
    26.                         samplerCUBE _TexRight;
    27.                 half4 _TexLeft_HDR;
    28.                 half4 _TexRight_HDR;
    29.  
    30.                 half4 _Tint;
    31.                 half _Exposure;
    32.                 float _Rotation;
    33.  
    34.                 float3 RotateAroundYInDegrees(float3 vertex, float degrees)
    35.                 {
    36.                     float alpha = degrees * UNITY_PI / 180.0;
    37.                     float sina, cosa;
    38.                     sincos(alpha, sina, cosa);
    39.                     float2x2 m = float2x2(cosa, -sina, sina, cosa);
    40.                     return float3(mul(m, vertex.xz), vertex.y).xzy;
    41.                 }
    42.  
    43.                 struct appdata_t {
    44.                     float4 vertex : POSITION;
    45.                     UNITY_VERTEX_INPUT_INSTANCE_ID
    46.                 };
    47.  
    48.                 struct v2f {
    49.                     float4 vertex : SV_POSITION;
    50.                     float3 texcoord : TEXCOORD0;
    51.                     UNITY_VERTEX_OUTPUT_STEREO
    52.                 };
    53.  
    54.                 v2f vert(appdata_t v)
    55.                 {
    56.                     v2f o;
    57.                     UNITY_SETUP_INSTANCE_ID(v);
    58.                     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    59.                     float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
    60.                     o.vertex = UnityObjectToClipPos(rotated);
    61.                     o.texcoord = v.vertex.xyz;
    62.                     return o;
    63.                 }
    64.  
    65.                 fixed4 frag(v2f i) : SV_Target
    66.                 {
    67.                     UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
    68.  
    69.                     half4 tex;
    70.                     half3 c;
    71.  
    72.                     if (unity_StereoEyeIndex == 0) {
    73.                         // Left Eye
    74.                         tex = texCUBE(_TexLeft, i.texcoord);
    75.                         c = DecodeHDR(tex, _TexRight_HDR);
    76.                     }
    77.          else {
    78.                         // Right Eye
    79.                         tex = texCUBE(_TexRight, i.texcoord);
    80.                         //tex = half4(1,0,0,1);
    81.                         c = DecodeHDR(tex, _TexRight_HDR);
    82.                     }
    83.  
    84.                     c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
    85.                     c *= _Exposure;
    86.                     return half4(c, 1);
    87.                 }
    88.                 ENDCG
    89.             }
    90.     }
    91.  
    92.  
    93.         Fallback Off
    94.  
    95. }
    I feel like it would be around the //Left Eye //Right Eye comments that I would like to assign the proper layers.
     
    Last edited: Dec 6, 2022
  2. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    228
    Skybox/Panoramic shader for sky material is not working?
     
  3. arfish

    arfish

    Joined:
    Jan 28, 2017
    Posts:
    782
    Are you sure the seam is from the spheres, and not mipmaps in the Texture settings?
     
  4. jthiess

    jthiess

    Joined:
    Nov 5, 2018
    Posts:
    31
    The textures have "Generate Mip Maps" enabled. Should this not be the case?
     
  5. jthiess

    jthiess

    Joined:
    Nov 5, 2018
    Posts:
    31
    The images are TopBottom stereoscopic, so the Skybox/Panormaic shader renders the images stacked.
     
  6. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    228
    I am using panoramic skybox shader with over/under stereoscopic render.
    https://forum.unity.com/threads/how-to-stereoscopic-image-to-skybox-dome-for-vr.1257765/

    Check if in your unity version (old) has Skybox/Panoramic shader "3D Layout" option.

    This video shows Quest 2 stereoscopic render from Blender. This pictures creates fully 3D depth in headset.

    Of course 3DOF only...
     
    Last edited: Dec 8, 2022
  7. jthiess

    jthiess

    Joined:
    Nov 5, 2018
    Posts:
    31
    Unfortunately, the Panoramic shader in my Unity version doesn't have the 3DLayout option.
    upload_2022-12-7_10-24-13.png
     
  8. fuzzy3d

    fuzzy3d

    Joined:
    Jun 17, 2009
    Posts:
    228
    So, you need to create better 3D sphere in MAX, Blender... with better geometry at poles. Native Unity sphere is not good, problem is not in stereoscopic (or classic mono 360x180 panorama) image.
     
  9. jthiess

    jthiess

    Joined:
    Nov 5, 2018
    Posts:
    31
    I made a new sphere in Blender which really helped fix the seams of the equirectangular image but there was a little wrinkle still present. This wrinkle was fixed by turning off Generate MipMaps.

    Problem solved, thank you all!
     
    fuzzy3d likes this.