Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

stereo 3D in Unity 3D

Discussion in 'Made With Unity' started by phoberman, Oct 15, 2010.

  1. phoberman

    phoberman

    Joined:
    Jan 16, 2008
    Posts:
    74
    First there was this thread on stereoscopic imaging:

    http://forum.unity3d.com/threads/11775

    Then these guys wrapped the whole thing up in a script packaged it with a shader, materials, etc.

    http://forum.unity3d.com/threads/60961

    Now I've tweaked it all, added options for Side-by-Side, Over-Under, Swap Left/Right, etc, along with a GUI interface.

    Instructions are contained in the main script ("stereokopix3D.js").

    Enjoy let me know if it works for you - I'm on Mac, Unity Pro 3, haven't tested under Windows. Unity Pro required.


    *** UPDATE!! VERSION 025:

    http://forum.unity3d.com/threads/63874-stereo-3D-in-Unity-3D?p=416458#post416458

    *** UPDATE!!! VERSION 2.0!!!

    What began as this little package has grown into a full-featured stereo toolkit available for FREE on the Unity Asset Store:

    http://forum.unity3d.com/threads/140508-Stereoskopix-FOV2GO-V2-Stereo-3D-amp-VR-for-FREE!-Released
     
    Last edited: Jul 1, 2012
  2. sandolkakos

    sandolkakos

    Joined:
    Jun 3, 2009
    Posts:
    282
    wowww, this is amazing.
    Thanks to all people who worked in this system.

    here my test using Optimized Anaglyph Material:

     
    Last edited: Oct 15, 2010
  3. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    537
    great help man.
     
  4. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    537
    Is there any option for Active stereoscopy for shutter glasses and 3Dr eady projectors or check board pattern for 3D ready TVs?
     
  5. phoberman

    phoberman

    Joined:
    Jan 16, 2008
    Posts:
    74
    No, but I noticed your post from a few months back regarding active stereo, and I'd be very interested in any method for doing it - I'm afraid that's beyond my skills (much better at stereography than programming) Same with checkerboard, or interlaced.

    There was this post a while back: http://forum.unity3d.com/threads/31837 but I could never get it to work.

    So certainly if you or anyone else is working on any of this, I'd love to know about it, and would gladly incorporate additional display modes into the project.

    By the way, the Side-by-Side Over-Under modes should work with the current version of 3D TVs - I've tested it with a Sony Bravia and it looks fantastic.
     
  6. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,598
    Hopefully in the next release they will just include all this as part of the standard assets package.
     
  7. phoberman

    phoberman

    Joined:
    Jan 16, 2008
    Posts:
    74
  8. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    537
    agree with you. So i had my vote for it.
    I also tried my best but never get the perfect solution, and useless solutions are not good to be shared is what i think.

    One more question to, you is does this script uses GPU power?, as i found some GL class in it.

    thanks
    rahu
     
  9. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    255
    You can find scripts for both line-interlaced and checkerboard stereo in the forum. However, these shaders had a bug which prevented them from producing any useful results. You can find the checkerboard script and a link to the line-interlacing script (the only difference between the two approaches is the line with "fmod" in the shader) in this thread, in addition to my answer that fixes the shader bug:

    http://forum.unity3d.com/threads/57498-Active-Stereoscopy-using-DLP-TV

    @rahuxx: There is still this thread from you, where you claim you already solved the generation of a 120Hz frame interleaved active shutter signal with Unity, but you never posted your solution, or explained how you did this. However, you asking in this thread whether anybody managed to do active stereo with Unity kinda contradicts that. So do you have a solution for it or not?

    http://forum.unity3d.com/threads/54590-Any-one-intrested-in-native-stereoscopy-in-Unity3D
     
  10. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    255
    Concerning Side-by-Side rendering for passive stereo:

    Note, besides DualHead2Go and ATI EyeFinity / nvidia Surround, there is a tweak which allows Unity to render fullscreen to a wide desktop, which you can then display using the "normal" Windows DualView/multiple Displays setup.

    The trick is to create a custom resolution (with the nvidia control panel) that is 1 pixel less than your desired wide resolution. Once this resolution is defined, it is available to Unity's resolution dialog. Start the app with that resolution (windowed, not fullscreen!), and the resulting window will fill the available space as good as possible (except for the window decorations/borders/title bar). With tools such as AutoHotKey you can get rid of these decorations, and have a fullscreen image. The disadvantage, however, is that the rendering canvas will be scaled, not resized, when hiding the window decorations, so your anti-aliasing will lose some quality (unless you have AA disabled, in which case you will gain some anti-aliasing).

    For example, if you have 2 monitors with 720p each (=1280x720), create a custom resolution for 2559x719. Don't actually use that resolution, keep your monitors at 1280x720.

    This thread describes this workaround in detail: http://forums.darkfallonline.com/showthread.php?t=242644
     
  11. phoberman

    phoberman

    Joined:
    Jan 16, 2008
    Posts:
    74
    Wolfram, thanks for the pointers to the interlaced checkerboard stuff. I've incorporated all of that into the project, cleaned it up fixed a bunch of other stuff so that all the settings can be changed via the GUI (anaglyph types, interlace resolutions, etc).

    I should mention that I'm a novice at shaders, so I don't know how correct or robust any of this is. And I haven't tested it extensively, so if any problems crop up, let me know, especially if you have any insight into how to fix them. Also, there's no documentation to speak of, but hopefully it's all reasonably self-explanatory. Any questions, ask.

    Anyway, I'd still love to see Unity add native support for stereo (with at least anaglyph for indie + iphone). We really need to be able to use active 120Hz systems - but now at least we've got a workaround for the other display modes.

    [Minor update v027 - a few more keyboard shortcuts, alt-click on object to track]
     

    Attached Files:

    Last edited: Nov 8, 2010
  12. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    537

    yes i have it in the past but for very light weight project when it goes higher in mesh it is not so useful. That is why i started that thread to find how many peoples are interested in it and if any one is able to help me, if you can help me then i can share code with you. PM me, describe your experience in stereoscopy to help me learn more about you and your project on stereoscopy.
     
  13. Ekzuzy

    Ekzuzy

    Joined:
    May 28, 2008
    Posts:
    34
    I've seen somewhere that somebody has already managed to fix and clean solution I've provided with interlaced stereoscopy. But if You are interested, I can post our solution which we have also fixed so it works on Windows and MacOS (and D3D too, or at least as far as I remember - it was a long time ago ;-)). It is for Unity 2.61, we haven't migrated to 3.x yet (don't have time right now). But it works.
    We have also added the possibility to change camera's projection matrix from symetrical to asymetrical. So it appears like one is watching through the window on the scene - you have bigger depth in the scene. But it is also very easy to change the focal length which enables objects to stick out of the screen (all objects that are positioned between camera's near clipping plane and the focal length distance stick out of the screen, so one can change how much scene is in front of the screen and how much behind it).
     
  14. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    537
    yes Ekzuzy, i would like to try if you can share.
     
  15. Artimese

    Artimese

    Joined:
    Nov 22, 2009
    Posts:
    794
    This is freakin awesome, it beats the other ones by a long shot, the anti alising on the red and blue is perfect, seems like something from nvidias sterioscopic options :p
     
  16. giancamati

    giancamati

    Joined:
    Aug 4, 2010
    Posts:
    518
    That's EPIC, but the problem I have that for whatever reason the package doesn't activate the sync signal of my graphics card so... how can I possibly do that? I need the 120Hz out of my graphics card when the apps starts.

    Thanks,
    GC.
     
  17. jerome

    jerome

    Joined:
    Oct 13, 2008
    Posts:
    53
    Very cool,
    A big question is how to make a GUI in Side-by-side stereo for exemple ? I have some problem :
    - The GUI is always shown on the full screen
    -> I partially resolve this : attach two identical script with the gui on each cam and modify pos and scale with GUI.matrix. BUT if I create a button there is in fact two independent button
    -> When viewed on a 3d screen the cursor can leave the screen or go from left to right side
     
  18. Snake-YAVA

    Snake-YAVA

    Joined:
    Jul 18, 2011
    Posts:
    3

    phoberman, I beginer in C# and in Unity. Can you add possibility of a conclusion to two monitors (for the mirror stereomonitor)? (As it becomes in a 3D-image, 3D-video stereoviewer http://sview.ru/en/ )
    sView is able to deduce a stereo in a window mode.
    It is actually necessary to deduce side-by-side, but only on two windows, or on one window developed on all screen and with the double width.
    I can resize window by SetResolution function, but can not remove titlebar.
    Sorry for my bad English.
     
  19. asnane

    asnane

    Joined:
    Nov 23, 2010
    Posts:
    8
    great job.
     
  20. Snake-YAVA

    Snake-YAVA

    Joined:
    Jul 18, 2011
    Posts:
    3
    Dual window or single window (with double resolution) - it's possible in Unity? See my up post.
     
  21. imin

    imin

    Joined:
    Feb 24, 2010
    Posts:
    29
    Hi,
    MiddleVR for Unity can provide active stereoscopy (OpenGL quad-buffer), and side-by-side (compressed or not) stereo.
    You can download a trial version on the webpage : http://www.imin-vr.com

    Cheers,
    cb
     
  22. negative11

    negative11

    Joined:
    Jun 27, 2012
    Posts:
    9
    @phoberman: hw do u attach the shaders to the script?...tqs...
     
  23. harrington

    harrington

    Joined:
    Jul 10, 2012
    Posts:
    43
    What would be the simplest way to extend this script to allow a non-stereoscopy option? I've tried tricks like turning the inter-axial distance to 0, though this results in the frame rate being half of what it should be.

    Is there a way to disable the stereoscopy component and continue using the camera?

    Thanks!
     
  24. ludiares

    ludiares

    Joined:
    Jul 14, 2011
    Posts:
    242
    Why do you want to turn a stereoscopy script to non stereo, i mean, to a normal camera? It's as simple as using a normal camera without those scripts
     
  25. sleiN13

    sleiN13

    Joined:
    Sep 26, 2012
    Posts:
    2
    Thanks to this script I'm able to produce side-by-side stereoscopic 3d that I use as input for my Sony hmz-t1. The only problem I found is that I have to setup my Sony hmd every time I start the virtual world or switch from window (alt+tab).

    Every time Unity receives the focus it seem to reinitialize the monitor resolution (same during startup) and that in turn will reset the sony HMD 3D settings.

    (1) Is there a way to tell unity not to change/modify/touch the screen resolution so that this doesn't happen anymore?

    Or what would be even better is to let Unity output the video signal with the hmdi 1.4 3d flag to side-by-side (Last post).

    (2) Is it possible to let unity do this or influence unity in a way it does do it?

    I found a Unity plugin that suggest that they can do it Link to plugin. But they don't tell how it is done and I can't find any documentation about the subject in the unity forums.

    [edit]
    Enableling the Run in background option in the player seem to fix problem (1). You still need to set the stereo mode on the HMD at startup. Doing this automatically with the hmdi flag is still preffered
    [/edit]
     
    Last edited: Oct 8, 2012
  26. bjonreyes

    bjonreyes

    Joined:
    Feb 1, 2013
    Posts:
    4
    Hi phoberman.

    I fixed your stereoskopix3Dv027demo.unitypackage for my 1Ghz single core Gadmei T883 3D tablet to remove its blackness when its played on my tablet. Can you fix its lag when its played on tablets like my own?


     

    Attached Files:

  27. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    537

    Hey, How you activate 3D in that tab?
    I have it and want to try.
    Can you guide me?
    rahu
     
  28. TritonHorse

    TritonHorse

    Joined:
    Mar 7, 2015
    Posts:
    1
    Hi all, I try to import stereoskopix3Dv27demo to Unity 5, so I must Run API Updater to make it work,but when play, it show this error:

    line of code:
    Code (JavaScript):
    1. leftCam.camera.CopyFrom (GetComponent.<Camera>());
    entire Old Script before API updater:
    Code (JavaScript):
    1. /*
    2. .-------------------------------------------------------------------
    3. |  Unity Stereoskopix 3D v027
    4. |-------------------------------------------------------------------
    5. |  This all started when TheLorax began this thread:
    6. |  http://forum.unity3d.com/threads/11775
    7. |-------------------------------------------------------------------
    8. |  There were numerous contributions to the thread from
    9. |  aNTeNNa trEE, InfiniteAlec, Jonathan Czeck, monark and others.
    10. |-------------------------------------------------------------------
    11. |  checco77 of Esimple Studios wrapped the whole thing up
    12. |  in a script & packaged it with a shader, materials, etc.
    13. |  http://forum.unity3d.com/threads/60961
    14. |  Esimple included a copyright & license:
    15. |  Copyright (c) 2010, Esimple Studios All Rights Reserved.
    16. |  License: Distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
    17. | ------------------------------------------------------------------
    18. |  I tweaked everything, added options for Side-by-Side, Over-Under,
    19. |  Swap Left/Right, etc, along with a GUI interface:
    20. |  http://forum.unity3d.com/threads/63874
    21. |-------------------------------------------------------------------
    22. |  Wolfram then pointed me to shaders for interlaced/checkerboard display.
    23. |-------------------------------------------------------------------
    24. |  In this version (v026), I added Wolfram's additional display modes,
    25. |  moved Esimple's anaglyph options into the script (so that only one
    26. |  material is needed), and reorganized the GUI.
    27. |-------------------------------------------------------------------
    28. |  The package consists of
    29. |  1) this script ('stereoskopix3D.js')
    30. |  2) a shader ('stereo3DViewMethods.shader')
    31. |  3) a material ('stereo3DMat')
    32. |  4) a demo scene ('demoScene3D.scene') - WASD or arrow keys travel,
    33. |     L button grab objects, L button lookaround when GUI hidden.
    34. |-------------------------------------------------------------------
    35. |  Instructions: (NOTE: REQUIRES UNITY PRO)
    36. |  1. Drag this script onto your camera.
    37. |  2. Drag 'stereoMat' into the 'Stereo Materials' field.
    38. |  3. Hit 'Play'.
    39. |  4. Adjust parameters with the GUI controls, press the tab key to toggle.
    40. |  5. To save settings from the GUI, copy them down, hit 'Stop',
    41. |     and enter the new settings in the camera inspector.
    42. '-------------------------------------------------------------------
    43. |  Perry Hoberman <hoberman (at) bway.net
    44. |-------------------------------------------------------------------
    45. */
    46.  
    47. @script RequireComponent (Camera)
    48. @script AddComponentMenu ("stereoskopix/stereoskopix3D")
    49.  
    50. private var leftCamRT;  
    51. private var rightCamRT;
    52. private var leftCam;
    53. private var rightCam;
    54.  
    55. public var stereoMaterial : Material;
    56.  
    57. enum mode3D {Anaglyph, SideBySide, OverUnder,Interlace,Checkerboard};
    58. private var modeStrings : String[] = ["Anaglyph", "Side By Side","Over Under","Interlace","Checkerboard"];
    59. public var format3D = mode3D.Anaglyph;
    60. enum anaType {Monochrome, HalfColor, FullColor, Optimized, Purple};
    61. private var anaStrings : String[] = ["Gray", "Half Color", "Color", "Optimized", "Magenta"];
    62. public var anaglyphOptions = anaType.HalfColor;
    63.  
    64. enum modeSBS {Squeezed,Unsqueezed};
    65. private var sbsStrings : String[] = ["Squeezed","Unsqueezed"];
    66. public var sideBySideOptions = modeSBS.Squeezed;
    67.  
    68. public var interlaceRows : int = 1080;
    69. public var checkerboardColumns : int = 1920;
    70. public var checkerboardRows : int = 1080;
    71.  
    72. public var interaxial : float = 0.25;
    73. public var zeroParallax : float = 6.0;
    74. private var toParallax : float = 6.0;
    75. public var fieldOfView : float = 60.0;
    76.  
    77. public var GuiVisible : boolean = true;
    78. public var ToggleGuiKey : KeyCode = KeyCode.Tab;
    79. public var ToggleToeInKey : KeyCode = KeyCode.P;
    80. public var LeftRightKey : KeyCode = KeyCode.Y;
    81. public var LeftOnlyKey : KeyCode = KeyCode.U;
    82. public var RightOnlyKey : KeyCode = KeyCode.I;
    83. public var RightLeftKey : KeyCode = KeyCode.O;
    84. public var trackObjKey : KeyCode = KeyCode.T;
    85.  
    86. enum method3D {Parallel,ToedIn};
    87. private var methodStrings : String[] = ["Parallel", "Toed In"];
    88. public var cameraMethod = method3D.Parallel;
    89.  
    90. enum cams3D {LeftRight, LeftOnly, RightOnly, RightLeft};
    91. private var camStrings : String[] = ["Left/Right ["+LeftRightKey+"]", "LeftOnly ["+LeftOnlyKey+"]", "RightOnly ["+RightOnlyKey+"]", "Right/Left ["+RightLeftKey+"]"];
    92. public var cameraSelect = cams3D.LeftRight;
    93.  
    94. public var cameraAspect : float = 1.33;
    95. public var saveCustomAspect: boolean = false;
    96.  
    97. private var windowRect : Rect = Rect(20,20,600,300);
    98.  
    99. private var mouseLookScript;    // find MouseLookButton script
    100. private var dummy : boolean = false;    // dummy button to get focus off text fields
    101.  
    102. private var toggleTrackObj : boolean = false;
    103. private var trackObject : GameObject;
    104.  
    105. function Start () {
    106.     if (!stereoMaterial) {
    107.         Debug.LogError("No Stereo Material Found. Please drag 'stereoMat' into the Stereo Material Field");
    108.         this.enabled = false;
    109.         return;
    110.     }
    111.     leftCam = new GameObject ("leftCam", Camera);
    112.     rightCam = new GameObject ("rightCam", Camera);
    113.  
    114.     leftCam.camera.CopyFrom (camera);
    115.     rightCam.camera.CopyFrom (camera);
    116.    
    117.     leftCam.camera.renderingPath = camera.renderingPath;
    118.     rightCam.camera.renderingPath = camera.renderingPath;
    119.    
    120.     fieldOfView = camera.fieldOfView;
    121.     if (saveCustomAspect) {
    122.         camera.aspect = cameraAspect;
    123.     } else {
    124.         cameraAspect = camera.aspect;
    125.     }
    126.    
    127.     leftCam.AddComponent(GUILayer);
    128.     rightCam.AddComponent(GUILayer);
    129.    
    130.     leftCamRT = new RenderTexture (Screen.width, Screen.height, 24);
    131.     rightCamRT = new RenderTexture (Screen.width, Screen.height, 24);
    132.    
    133.     leftCam.camera.targetTexture = leftCamRT;
    134.     rightCam.camera.targetTexture = rightCamRT;
    135.      
    136.     stereoMaterial.SetTexture ("_LeftTex", leftCamRT);
    137.     stereoMaterial.SetTexture ("_RightTex", rightCamRT);
    138.    
    139.     leftCam.camera.depth = camera.depth -2;
    140.     rightCam.camera.depth = camera.depth -1;
    141.    
    142.     UpdateView();
    143.  
    144.     leftCam.transform.parent = transform;
    145.     rightCam.transform.parent = transform;
    146.    
    147.     camera.cullingMask = 0;
    148.     camera.backgroundColor = Color (0,0,0,0);
    149.     camera.clearFlags = CameraClearFlags.Nothing;
    150.  
    151.     mouseLookScript = camera.GetComponent("MouseLookButton"); // deactivate MouseLookButton script (if it exists) when GUI visible  
    152. }
    153.  
    154. function Update () {
    155.     if (Input.GetKeyUp(ToggleGuiKey)) {
    156.         GuiVisible = !GuiVisible;
    157.     } else if (Input.GetKeyUp(trackObjKey)) {
    158.         toggleTrackObj = !toggleTrackObj;
    159.     } else if (Input.GetKeyUp(LeftRightKey)) {
    160.          cameraSelect = cams3D.LeftRight;
    161.     } else if (Input.GetKeyUp(LeftOnlyKey)) {
    162.         cameraSelect = cams3D.LeftOnly;
    163.     } else if (Input.GetKeyUp(RightOnlyKey)) {
    164.         cameraSelect = cams3D.RightOnly;
    165.     } else if (Input.GetKeyUp(RightLeftKey)) {
    166.         cameraSelect = cams3D.RightLeft;
    167.     } else if (Input.GetKeyUp(ToggleToeInKey)) {
    168.         if (cameraMethod == method3D.ToedIn) {
    169.             cameraMethod = method3D.Parallel;
    170.         } else {
    171.             cameraMethod = method3D.ToedIn;
    172.         }
    173.     } else if (Input.GetKey("-")) {
    174.         if (Input.GetKey(KeyCode.LeftShift)) {
    175.             interaxial -= 0.01;
    176.         } else {
    177.             interaxial -= 0.001;
    178.         }
    179.         interaxial = Mathf.Max(interaxial,0);
    180.     } else if (Input.GetKey("=")) {
    181.         if (Input.GetKey(KeyCode.LeftShift)) {
    182.             interaxial += 0.01;
    183.         } else {
    184.             interaxial += 0.001;
    185.         }
    186.     } else if (Input.GetKey("[")) {
    187.         if (Input.GetKey(KeyCode.LeftShift)) {
    188.             zeroParallax -= 0.1;
    189.         } else {
    190.             zeroParallax -= 0.01;
    191.         }
    192.         zeroParallax = Mathf.Max(zeroParallax,1);
    193.     } else if (Input.GetKey("]")) {
    194.         if (Input.GetKey(KeyCode.LeftShift)) {
    195.             zeroParallax += 0.1;
    196.         } else {
    197.             zeroParallax += 0.01;
    198.         }
    199.     }
    200.      if (Input.GetMouseButtonDown(0) && Input.GetKey(KeyCode.LeftAlt)) {
    201.         toParallax = convergeOnObject();
    202.         LerpZero (zeroParallax,toParallax,1.0);
    203.     } else if (trackObject && toggleTrackObj) {
    204.         convergeTrackObject();
    205.     }
    206.  
    207. }
    208.  
    209. function LerpZero(start:float, end:float, speed: float) {
    210.     var t = 0.0;
    211.     var rate = 1.0/speed;
    212.     while (t < 1.0) {
    213.         t += Time.deltaTime * rate;
    214.         zeroParallax = Mathf.Lerp(start,end,t);
    215.         yield;
    216.     }
    217. }
    218.  
    219. function convergeOnObject() {
    220.     var hit: RaycastHit;
    221.     var ray : Ray = leftCam.camera.ScreenPointToRay (Input.mousePosition);    // converge to clicked point
    222.     if (Physics.Raycast (ray, hit, 100.0)) {
    223.         trackObject = hit.collider.gameObject;
    224.         //zeroParallax = Vector3.Distance(transform.position,hit.collider.gameObject.transform.position); // converge to center of object
    225.         newZero = hit.distance;
    226.         return newZero;
    227.     }
    228. }
    229.  
    230. function convergeTrackObject() {
    231.       var planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
    232.        //if(vec.x>0 && vec.x<1 && vec.y>0 && vec.y<1 && vec.z>0) { // alternate to bounds - just check object center
    233.       if (GeometryUtility.TestPlanesAABB(planes,trackObject.collider.bounds)) {
    234.         //Debug.Log(trackObject.name+" is ON CAMERA");
    235.         var hit: RaycastHit;
    236.           var vec : Vector3 = Camera.main.WorldToViewportPoint(trackObject.transform.position);
    237.         var ray : Ray = Camera.main.ViewportPointToRay (vec);
    238.         if (Physics.Raycast(ray,hit,100.0)) {
    239.             if (hit.collider.gameObject == trackObject && hit.distance > Camera.main.nearClipPlane) {
    240.                 zeroParallax = hit.distance;
    241.             } else {
    242.                 //Debug.Log(trackObject.name+" is ON BUT HIDDEN");
    243.             }
    244.         }
    245.     } else {
    246.         //Debug.Log(trackObject.name+ " is OFF CAMERA");
    247.     }
    248. }
    249.  
    250. function LateUpdate() {
    251.     UpdateView();
    252. }
    253.  
    254. function UpdateView() {
    255.     switch (cameraSelect) {
    256.         case cams3D.LeftRight:
    257.             leftCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    258.             rightCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    259.             break;
    260.         case cams3D.LeftOnly:
    261.             leftCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    262.             rightCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    263.             break;
    264.         case cams3D.RightOnly:
    265.             leftCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    266.             rightCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    267.             break;
    268.         case cams3D.RightLeft:
    269.             leftCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    270.             rightCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    271.             break;
    272.     }
    273.     if (cameraMethod == method3D.ToedIn) {
    274.         leftCam.camera.projectionMatrix = camera.projectionMatrix;
    275.         rightCam.camera.projectionMatrix = camera.projectionMatrix;
    276.         leftCam.transform.LookAt (transform.position + (transform.TransformDirection (Vector3.forward) * zeroParallax));
    277.         rightCam.transform.LookAt (transform.position + (transform.TransformDirection (Vector3.forward) * zeroParallax));
    278.     } else {
    279.         leftCam.transform.rotation = transform.rotation;
    280.         rightCam.transform.rotation = transform.rotation;
    281.         switch (cameraSelect) {
    282.             case cams3D.LeftRight:
    283.                 leftCam.camera.projectionMatrix = projectionMatrix(true);
    284.                 rightCam.camera.projectionMatrix = projectionMatrix(false);
    285.                 break;
    286.             case cams3D.LeftOnly:
    287.                 leftCam.camera.projectionMatrix = projectionMatrix(true);
    288.                 rightCam.camera.projectionMatrix = projectionMatrix(true);
    289.                 break;
    290.             case cams3D.RightOnly:
    291.                 leftCam.camera.projectionMatrix = projectionMatrix(false);
    292.                 rightCam.camera.projectionMatrix = projectionMatrix(false);
    293.                 break;
    294.             case cams3D.RightLeft:
    295.                 leftCam.camera.projectionMatrix = projectionMatrix(false);
    296.                 rightCam.camera.projectionMatrix = projectionMatrix(true);
    297.                 break;
    298.         }
    299.     }
    300. }
    301.  
    302. function OnRenderImage (source:RenderTexture, destination:RenderTexture) {
    303.    RenderTexture.active = destination;
    304.    GL.PushMatrix();
    305.    GL.LoadOrtho();
    306.    switch (format3D) {
    307.        case mode3D.Anaglyph:
    308.            stereoMaterial.SetPass(0);
    309.           DrawQuad(0);
    310.        break;
    311.        case mode3D.SideBySide:
    312.        case mode3D.OverUnder:
    313.         for(var i:int = 1; i <= 2; i++) {
    314.             stereoMaterial.SetPass(i);
    315.             DrawQuad(i);
    316.         }
    317.     break;
    318.     case mode3D.Interlace:
    319.     case mode3D.Checkerboard:
    320.         stereoMaterial.SetPass(3);
    321.         DrawQuad(3);
    322.        break;
    323.        default:
    324.        break;
    325.    }
    326.    GL.PopMatrix();
    327. }
    328.  
    329. function OnGUI () {
    330.        if (GuiVisible) {
    331.         windowRect = GUILayout.Window (0, windowRect, DoWindow, "Stereoskopix 3D Controls");
    332.         if (mouseLookScript) mouseLookScript.suppress = true;
    333.     } else {
    334.         if (mouseLookScript) mouseLookScript.suppress = false;
    335.     }
    336. }
    337.  
    338. function DoWindow (windowID : int) {
    339.     GUILayout.BeginHorizontal();
    340.         GUILayout.BeginVertical();
    341.             GUILayout.BeginHorizontal();
    342.                 GUILayout.FlexibleSpace();
    343.                 GUILayout.Label ("Mode");
    344.                 GUILayout.FlexibleSpace();
    345.             GUILayout.EndHorizontal();
    346.             format3D = GUILayout.SelectionGrid (format3D, modeStrings,1,GUILayout.MaxWidth(100));
    347.             if (GUI.changed) {
    348.                 if (format3D == mode3D.Interlace) {
    349.                     SetWeave(0);
    350.                 } else if (format3D == mode3D.Checkerboard) {
    351.                     SetWeave(1);
    352.                 }
    353.             }
    354.         GUILayout.EndVertical();
    355.         GUILayout.BeginVertical();
    356.             GUILayout.BeginHorizontal();
    357.                 GUILayout.FlexibleSpace();
    358.                 GUILayout.Label ("Options");
    359.                 GUILayout.FlexibleSpace();
    360.             GUILayout.EndHorizontal();
    361.             GUILayout.BeginHorizontal();
    362.                 GUILayout.Space(15);
    363.                 anaglyphOptions = GUILayout.Toolbar (anaglyphOptions, anaStrings,GUILayout.MaxWidth(500));
    364.                 if (GUI.changed) {
    365.                     SetAnaglyphType();
    366.                 }
    367.             GUILayout.EndHorizontal();
    368.             GUILayout.BeginHorizontal();
    369.                 GUILayout.Space(15);
    370.                 sideBySideOptions = GUILayout.Toolbar (sideBySideOptions, sbsStrings,GUILayout.MaxWidth(200));
    371.             GUILayout.EndHorizontal();
    372.             GUILayout.BeginHorizontal();
    373.                 GUILayout.FlexibleSpace();
    374.                 GUILayout.Label ("[Alt-Click on Object to Converge]");
    375.             GUILayout.EndHorizontal();
    376.             GUILayout.BeginHorizontal();
    377.                 GUILayout.Space(15);
    378.                 GUILayout.Label ("Rows",GUILayout.MinWidth(60));
    379.                 interlaceString = System.Convert.ToString(interlaceRows);
    380.                 interlaceString = GUILayout.TextField (interlaceString,4,GUILayout.MaxWidth(50));
    381.                 interlaceRows = System.Convert.ToDouble(interlaceString);
    382.                 if (GUI.changed) {
    383.                     if (format3D == mode3D.Interlace) {
    384.                         SetWeave(0);
    385.                     }
    386.                 }
    387.                 if (GUILayout.Button("-")) {
    388.                     interlaceRows -= 1;
    389.                     SetWeave(0);
    390.                 }
    391.                 if (GUILayout.Button("+")) {
    392.                     interlaceRows +=1;
    393.                     SetWeave(0);
    394.                 }        
    395.                 GUILayout.FlexibleSpace();
    396.                 toggleTrackObj = GUILayout.Toggle(toggleTrackObj, "Track Object [T]");
    397.             GUILayout.EndHorizontal();
    398.             GUILayout.BeginHorizontal();
    399.                 GUILayout.Space(15);
    400.                 GUILayout.Label ("Columns",GUILayout.MinWidth(60));
    401.                 checkerString = System.Convert.ToString(checkerboardColumns);
    402.                 checkerString = GUILayout.TextField (checkerString,4,GUILayout.MaxWidth(50));
    403.                 checkerboardColumns = System.Convert.ToDouble(checkerString);
    404.                 GUILayout.Label ("Rows");
    405.                 checkerString = System.Convert.ToString(checkerboardRows);
    406.                 checkerString = GUILayout.TextField (checkerString,4,GUILayout.MaxWidth(50));
    407.                 checkerboardRows = System.Convert.ToDouble(checkerString);
    408.                 if (GUI.changed) {
    409.                     if (format3D == mode3D.Checkerboard) {
    410.                         SetWeave(1);
    411.                     }
    412.                 }
    413.                 if (GUILayout.Button ("enter")) {
    414.                     GUI.FocusControl ("focus");
    415.                 }
    416.                 GUILayout.FlexibleSpace();
    417.                 GUILayout.Label("  ["+ToggleGuiKey+" toggles controls]");
    418.             GUILayout.EndHorizontal();
    419.         GUILayout.EndVertical();
    420.     GUILayout.EndHorizontal();
    421.     GUILayout.Space(15);
    422.     GUILayout.BeginHorizontal();
    423.             GUILayout.Label ("Camera Select",GUILayout.MinWidth(120));
    424.             GUILayout.Space(15);
    425.             cameraSelect = GUILayout.Toolbar (cameraSelect, camStrings,GUILayout.MaxWidth(400));
    426.             GUILayout.FlexibleSpace();
    427.     GUILayout.EndHorizontal();
    428.     GUILayout.BeginHorizontal();
    429.             GUILayout.Label ("Camera Method [P]",GUILayout.MinWidth(120));
    430.             GUILayout.Space(15);
    431.             cameraMethod = GUILayout.Toolbar (cameraMethod, methodStrings,GUILayout.MaxWidth(200));
    432.             GUILayout.FlexibleSpace();
    433.     GUILayout.EndHorizontal();
    434.     GUILayout.BeginHorizontal();
    435.         GUILayout.Label ("Interaxial  - +",GUILayout.MinWidth(120));
    436.         interaxial = GUILayout.HorizontalSlider (interaxial, 0.0, 5.0,GUILayout.MaxWidth(300));
    437.         GUILayout.Label (" "+interaxial);
    438.         GUILayout.FlexibleSpace();
    439.     GUILayout.EndHorizontal();
    440.     GUILayout.BeginHorizontal();
    441.         GUILayout.Label ("Zero Parallax  [ ] ",GUILayout.MinWidth(120));
    442.         zeroParallax = GUILayout.HorizontalSlider (zeroParallax, 1.0, 100.0,GUILayout.MaxWidth(300));
    443.         GUILayout.Label (" "+zeroParallax);
    444.         GUILayout.FlexibleSpace();
    445.     GUILayout.EndHorizontal();
    446.     GUILayout.BeginHorizontal();
    447.         GUILayout.Label ("Field of View",GUILayout.MinWidth(120));
    448.         fieldOfView = GUILayout.HorizontalSlider (fieldOfView, 1.0, 180.0,GUILayout.MaxWidth(300));
    449.         camera.fieldOfView = fieldOfView;
    450.         GUILayout.Label (" "+fieldOfView);
    451.         GUILayout.FlexibleSpace();
    452.     GUILayout.EndHorizontal();
    453.     GUILayout.BeginHorizontal();
    454.         GUILayout.Label ("Aspect Ratio",GUILayout.MinWidth(120));
    455.         if (GUILayout.Button("Reset")) {
    456.             camera.ResetAspect();
    457.             cameraAspect = camera.aspect;
    458.         }
    459.         cameraAspect = GUILayout.HorizontalSlider (cameraAspect, 0.1, 4.0,GUILayout.MaxWidth(250));
    460.         camera.aspect = cameraAspect;
    461.         GUILayout.Label (" "+cameraAspect);
    462.         GUILayout.FlexibleSpace();
    463.         GUI.SetNextControlName ("focus");
    464.         dummy = GUILayout.Toggle(dummy, "");
    465.  
    466.     GUILayout.EndHorizontal();
    467.     GUI.DragWindow();
    468. }
    469.  
    470. private function SetWeave(xy) {
    471.     if (xy) {
    472.         stereoMaterial.SetFloat("_Weave_X", checkerboardColumns);
    473.         stereoMaterial.SetFloat("_Weave_Y", checkerboardRows);
    474.     } else {
    475.         stereoMaterial.SetFloat("_Weave_X", 1);
    476.         stereoMaterial.SetFloat("_Weave_Y", interlaceRows);
    477.     }
    478. }
    479.  
    480. private function SetAnaglyphType() {
    481.    switch (anaglyphOptions) {
    482.            case anaType.Monochrome:
    483.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0.299,0.587,0.114,0));
    484.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    485.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    486.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    487.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0.299,0.587,0.114,0));
    488.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0.299,0.587,0.114,0));
    489.            break;
    490.            case anaType.HalfColor:
    491.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0.299,0.587,0.114,0));
    492.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    493.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    494.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    495.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,1,0,0));
    496.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0,0,1,0));
    497.            break;
    498.            case anaType.FullColor:
    499.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(1,0,0,0));
    500.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    501.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    502.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    503.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,1,0,0));
    504.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0,0,1,0));
    505.            break;
    506.            case anaType.Optimized:
    507.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0,0.7,0.3,0));
    508.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    509.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    510.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    511.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,1,0,0));
    512.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0,0,1,0));
    513.            break;
    514.            case anaType.Purple:
    515.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0.299,0.587,0.114,0));
    516.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    517.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    518.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    519.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,0,0,0));
    520.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0.299,0.587,0.114,0));
    521.            break;
    522.    }
    523. }
    524. private function DrawQuad(cam) {
    525.     if (format3D == mode3D.Anaglyph) {
    526.                GL.Begin (GL.QUADS);    
    527.               GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    528.               GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1, 0.0, 0.1 );
    529.               GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1, 1.0, 0.1 );
    530.               GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    531.                GL.End();
    532.     } else {
    533.         if (format3D==mode3D.SideBySide) {
    534.             if (cam==1) {
    535.                    GL.Begin (GL.QUADS);    
    536.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    537.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 0.5, 0.0, 0.1 );
    538.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 0.5, 1.0, 0.1 );
    539.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    540.                    GL.End();
    541.             } else {
    542.                    GL.Begin (GL.QUADS);    
    543.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.5, 0.0, 0.1 );
    544.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1.0, 0.0, 0.1 );
    545.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1.0, 1.0, 0.1 );
    546.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.5, 1.0, 0.1 );
    547.                    GL.End();
    548.             }
    549.         } else if (format3D == mode3D.OverUnder) {
    550.             if (cam==1) {
    551.                    GL.Begin (GL.QUADS);    
    552.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.5, 0.1 );
    553.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1.0, 0.5, 0.1 );
    554.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1.0, 1.0, 0.1 );
    555.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    556.                    GL.End();
    557.             } else {
    558.                    GL.Begin (GL.QUADS);    
    559.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    560.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1.0, 0.0, 0.1 );
    561.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1.0, 0.5, 0.1 );
    562.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 0.5, 0.1 );
    563.                    GL.End();
    564.             }
    565.         } else if (format3D == mode3D.Interlace || format3D == mode3D.Checkerboard) {
    566.                GL.Begin (GL.QUADS);    
    567.               GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    568.               GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1, 0.0, 0.1 );
    569.               GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1, 1.0, 0.1 );
    570.               GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    571.                GL.End();
    572.         }
    573.     }
    574. }
    575.  
    576. function PerspectiveOffCenter(
    577.     left : float, right : float,
    578.     bottom : float, top : float,
    579.     near : float, far : float ) : Matrix4x4 {      
    580.     var x =  (2.0 * near) / (right - left);
    581.     var y =  (2.0 * near) / (top - bottom);
    582.     var a =  (right + left) / (right - left);
    583.     var b =  (top + bottom) / (top - bottom);
    584.     var c = -(far + near) / (far - near);
    585.     var d = -(2.0 * far * near) / (far - near);
    586.     var e = -1.0;
    587.  
    588.     var m : Matrix4x4;
    589.     m[0,0] = x;  m[0,1] = 0;  m[0,2] = a;  m[0,3] = 0;
    590.     m[1,0] = 0;  m[1,1] = y;  m[1,2] = b;  m[1,3] = 0;
    591.     m[2,0] = 0;  m[2,1] = 0;  m[2,2] = c;  m[2,3] = d;
    592.     m[3,0] = 0;  m[3,1] = 0;  m[3,2] = e;  m[3,3] = 0;
    593.     return m;
    594. }
    595.  
    596. function projectionMatrix(isLeftCam : boolean) : Matrix4x4 {
    597.    var left : float;
    598.    var right : float;
    599.    var a : float;
    600.    var b : float;
    601.    var FOVrad : float;
    602.    var aspect: float = camera.aspect;
    603.    var tempAspect: float;
    604.    if (sideBySideOptions == modeSBS.Unsqueezed && format3D == mode3D.SideBySide) {
    605.            FOVrad = camera.fieldOfView / 90.0 * Mathf.PI;
    606.            tempAspect = aspect/2;
    607.    } else {
    608.            FOVrad = camera.fieldOfView / 180.0 * Mathf.PI;
    609.            tempAspect = aspect;
    610.    }
    611.    a = camera.nearClipPlane * Mathf.Tan(FOVrad * 0.5);
    612.    b = camera.nearClipPlane / (zeroParallax + camera.nearClipPlane);
    613.  
    614.    if (isLeftCam) {
    615.       left  = - tempAspect * a + (interaxial/2) * b;
    616.       right =   tempAspect * a + (interaxial/2) * b;
    617.    }
    618.    else {
    619.       left  = - tempAspect * a - (interaxial/2) * b;
    620.       right =   tempAspect * a - (interaxial/2) * b;
    621.    }
    622.  
    623.    return PerspectiveOffCenter(left, right, -a, a, camera.nearClipPlane, camera.farClipPlane);
    624.    
    625. }
    entire New script:
    Code (JavaScript):
    1. /*
    2. .-------------------------------------------------------------------
    3. |  Unity Stereoskopix 3D v027
    4. |-------------------------------------------------------------------
    5. |  This all started when TheLorax began this thread:
    6. |  http://forum.unity3d.com/threads/11775
    7. |-------------------------------------------------------------------
    8. |  There were numerous contributions to the thread from
    9. |  aNTeNNa trEE, InfiniteAlec, Jonathan Czeck, monark and others.
    10. |-------------------------------------------------------------------
    11. |  checco77 of Esimple Studios wrapped the whole thing up
    12. |  in a script & packaged it with a shader, materials, etc.
    13. |  http://forum.unity3d.com/threads/60961
    14. |  Esimple included a copyright & license:
    15. |  Copyright (c) 2010, Esimple Studios All Rights Reserved.
    16. |  License: Distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
    17. | ------------------------------------------------------------------
    18. |  I tweaked everything, added options for Side-by-Side, Over-Under,
    19. |  Swap Left/Right, etc, along with a GUI interface:
    20. |  http://forum.unity3d.com/threads/63874
    21. |-------------------------------------------------------------------
    22. |  Wolfram then pointed me to shaders for interlaced/checkerboard display.
    23. |-------------------------------------------------------------------
    24. |  In this version (v026), I added Wolfram's additional display modes,
    25. |  moved Esimple's anaglyph options into the script (so that only one
    26. |  material is needed), and reorganized the GUI.
    27. |-------------------------------------------------------------------
    28. |  The package consists of
    29. |  1) this script ('stereoskopix3D.js')
    30. |  2) a shader ('stereo3DViewMethods.shader')
    31. |  3) a material ('stereo3DMat')
    32. |  4) a demo scene ('demoScene3D.scene') - WASD or arrow keys travel,
    33. |     L button grab objects, L button lookaround when GUI hidden.
    34. |-------------------------------------------------------------------
    35. |  Instructions: (NOTE: REQUIRES UNITY PRO)
    36. |  1. Drag this script onto your camera.
    37. |  2. Drag 'stereoMat' into the 'Stereo Materials' field.
    38. |  3. Hit 'Play'.
    39. |  4. Adjust parameters with the GUI controls, press the tab key to toggle.
    40. |  5. To save settings from the GUI, copy them down, hit 'Stop',
    41. |     and enter the new settings in the camera inspector.
    42. '-------------------------------------------------------------------
    43. |  Perry Hoberman <hoberman (at) bway.net
    44. |-------------------------------------------------------------------
    45. */
    46.  
    47. @script RequireComponent (Camera)
    48. @script AddComponentMenu ("stereoskopix/stereoskopix3D")
    49.  
    50. private var leftCamRT;  
    51. private var rightCamRT;
    52. private var leftCam;
    53. private var rightCam;
    54.  
    55. public var stereoMaterial : Material;
    56.  
    57. enum mode3D {Anaglyph, SideBySide, OverUnder,Interlace,Checkerboard};
    58. private var modeStrings : String[] = ["Anaglyph", "Side By Side","Over Under","Interlace","Checkerboard"];
    59. public var format3D = mode3D.Anaglyph;
    60. enum anaType {Monochrome, HalfColor, FullColor, Optimized, Purple};
    61. private var anaStrings : String[] = ["Gray", "Half Color", "Color", "Optimized", "Magenta"];
    62. public var anaglyphOptions = anaType.HalfColor;
    63.  
    64. enum modeSBS {Squeezed,Unsqueezed};
    65. private var sbsStrings : String[] = ["Squeezed","Unsqueezed"];
    66. public var sideBySideOptions = modeSBS.Squeezed;
    67.  
    68. public var interlaceRows : int = 1080;
    69. public var checkerboardColumns : int = 1920;
    70. public var checkerboardRows : int = 1080;
    71.  
    72. public var interaxial : float = 0.25;
    73. public var zeroParallax : float = 6.0;
    74. private var toParallax : float = 6.0;
    75. public var fieldOfView : float = 60.0;
    76.  
    77. public var GuiVisible : boolean = true;
    78. public var ToggleGuiKey : KeyCode = KeyCode.Tab;
    79. public var ToggleToeInKey : KeyCode = KeyCode.P;
    80. public var LeftRightKey : KeyCode = KeyCode.Y;
    81. public var LeftOnlyKey : KeyCode = KeyCode.U;
    82. public var RightOnlyKey : KeyCode = KeyCode.I;
    83. public var RightLeftKey : KeyCode = KeyCode.O;
    84. public var trackObjKey : KeyCode = KeyCode.T;
    85.  
    86. enum method3D {Parallel,ToedIn};
    87. private var methodStrings : String[] = ["Parallel", "Toed In"];
    88. public var cameraMethod = method3D.Parallel;
    89.  
    90. enum cams3D {LeftRight, LeftOnly, RightOnly, RightLeft};
    91. private var camStrings : String[] = ["Left/Right ["+LeftRightKey+"]", "LeftOnly ["+LeftOnlyKey+"]", "RightOnly ["+RightOnlyKey+"]", "Right/Left ["+RightLeftKey+"]"];
    92. public var cameraSelect = cams3D.LeftRight;
    93.  
    94. public var cameraAspect : float = 1.33;
    95. public var saveCustomAspect: boolean = false;
    96.  
    97. private var windowRect : Rect = Rect(20,20,600,300);
    98.  
    99. private var mouseLookScript;    // find MouseLookButton script
    100. private var dummy : boolean = false;    // dummy button to get focus off text fields
    101.  
    102. private var toggleTrackObj : boolean = false;
    103. private var trackObject : GameObject;
    104.  
    105. function Start () {
    106.     if (!stereoMaterial) {
    107.         Debug.LogError("No Stereo Material Found. Please drag 'stereoMat' into the Stereo Material Field");
    108.         this.enabled = false;
    109.         return;
    110.     }
    111.     leftCam = new GameObject ("leftCam", Camera);
    112.     rightCam = new GameObject ("rightCam", Camera);
    113.  
    114.     leftCam.camera.CopyFrom (GetComponent.<Camera>());
    115.     rightCam.camera.CopyFrom (GetComponent.<Camera>());
    116.    
    117.     leftCam.camera.renderingPath = GetComponent.<Camera>().renderingPath;
    118.     rightCam.camera.renderingPath = GetComponent.<Camera>().renderingPath;
    119.    
    120.     fieldOfView = GetComponent.<Camera>().fieldOfView;
    121.     if (saveCustomAspect) {
    122.         GetComponent.<Camera>().aspect = cameraAspect;
    123.     } else {
    124.         cameraAspect = GetComponent.<Camera>().aspect;
    125.     }
    126.    
    127.     leftCam.AddComponent(GUILayer);
    128.     rightCam.AddComponent(GUILayer);
    129.    
    130.     leftCamRT = new RenderTexture (Screen.width, Screen.height, 24);
    131.     rightCamRT = new RenderTexture (Screen.width, Screen.height, 24);
    132.    
    133.     leftCam.camera.targetTexture = leftCamRT;
    134.     rightCam.camera.targetTexture = rightCamRT;
    135.      
    136.     stereoMaterial.SetTexture ("_LeftTex", leftCamRT);
    137.     stereoMaterial.SetTexture ("_RightTex", rightCamRT);
    138.    
    139.     leftCam.camera.depth = GetComponent.<Camera>().depth -2;
    140.     rightCam.camera.depth = GetComponent.<Camera>().depth -1;
    141.    
    142.     UpdateView();
    143.  
    144.     leftCam.transform.parent = transform;
    145.     rightCam.transform.parent = transform;
    146.    
    147.     GetComponent.<Camera>().cullingMask = 0;
    148.     GetComponent.<Camera>().backgroundColor = Color (0,0,0,0);
    149.     GetComponent.<Camera>().clearFlags = CameraClearFlags.Nothing;
    150.  
    151.     mouseLookScript = GetComponent.<Camera>().GetComponent("MouseLookButton"); // deactivate MouseLookButton script (if it exists) when GUI visible  
    152. }
    153.  
    154. function Update () {
    155.     if (Input.GetKeyUp(ToggleGuiKey)) {
    156.         GuiVisible = !GuiVisible;
    157.     } else if (Input.GetKeyUp(trackObjKey)) {
    158.         toggleTrackObj = !toggleTrackObj;
    159.     } else if (Input.GetKeyUp(LeftRightKey)) {
    160.          cameraSelect = cams3D.LeftRight;
    161.     } else if (Input.GetKeyUp(LeftOnlyKey)) {
    162.         cameraSelect = cams3D.LeftOnly;
    163.     } else if (Input.GetKeyUp(RightOnlyKey)) {
    164.         cameraSelect = cams3D.RightOnly;
    165.     } else if (Input.GetKeyUp(RightLeftKey)) {
    166.         cameraSelect = cams3D.RightLeft;
    167.     } else if (Input.GetKeyUp(ToggleToeInKey)) {
    168.         if (cameraMethod == method3D.ToedIn) {
    169.             cameraMethod = method3D.Parallel;
    170.         } else {
    171.             cameraMethod = method3D.ToedIn;
    172.         }
    173.     } else if (Input.GetKey("-")) {
    174.         if (Input.GetKey(KeyCode.LeftShift)) {
    175.             interaxial -= 0.01;
    176.         } else {
    177.             interaxial -= 0.001;
    178.         }
    179.         interaxial = Mathf.Max(interaxial,0);
    180.     } else if (Input.GetKey("=")) {
    181.         if (Input.GetKey(KeyCode.LeftShift)) {
    182.             interaxial += 0.01;
    183.         } else {
    184.             interaxial += 0.001;
    185.         }
    186.     } else if (Input.GetKey("[")) {
    187.         if (Input.GetKey(KeyCode.LeftShift)) {
    188.             zeroParallax -= 0.1;
    189.         } else {
    190.             zeroParallax -= 0.01;
    191.         }
    192.         zeroParallax = Mathf.Max(zeroParallax,1);
    193.     } else if (Input.GetKey("]")) {
    194.         if (Input.GetKey(KeyCode.LeftShift)) {
    195.             zeroParallax += 0.1;
    196.         } else {
    197.             zeroParallax += 0.01;
    198.         }
    199.     }
    200.      if (Input.GetMouseButtonDown(0) && Input.GetKey(KeyCode.LeftAlt)) {
    201.         toParallax = convergeOnObject();
    202.         LerpZero (zeroParallax,toParallax,1.0);
    203.     } else if (trackObject && toggleTrackObj) {
    204.         convergeTrackObject();
    205.     }
    206.  
    207. }
    208.  
    209. function LerpZero(start:float, end:float, speed: float) {
    210.     var t = 0.0;
    211.     var rate = 1.0/speed;
    212.     while (t < 1.0) {
    213.         t += Time.deltaTime * rate;
    214.         zeroParallax = Mathf.Lerp(start,end,t);
    215.         yield;
    216.     }
    217. }
    218.  
    219. function convergeOnObject() {
    220.     var hit: RaycastHit;
    221.     var ray : Ray = leftCam.camera.ScreenPointToRay (Input.mousePosition);    // converge to clicked point
    222.     if (Physics.Raycast (ray, hit, 100.0)) {
    223.         trackObject = hit.collider.gameObject;
    224.         //zeroParallax = Vector3.Distance(transform.position,hit.collider.gameObject.transform.position); // converge to center of object
    225.         newZero = hit.distance;
    226.         return newZero;
    227.     }
    228. }
    229.  
    230. function convergeTrackObject() {
    231.       var planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
    232.        //if(vec.x>0 && vec.x<1 && vec.y>0 && vec.y<1 && vec.z>0) { // alternate to bounds - just check object center
    233.       if (GeometryUtility.TestPlanesAABB(planes,trackObject.GetComponent.<Collider>().bounds)) {
    234.         //Debug.Log(trackObject.name+" is ON CAMERA");
    235.         var hit: RaycastHit;
    236.           var vec : Vector3 = Camera.main.WorldToViewportPoint(trackObject.transform.position);
    237.         var ray : Ray = Camera.main.ViewportPointToRay (vec);
    238.         if (Physics.Raycast(ray,hit,100.0)) {
    239.             if (hit.collider.gameObject == trackObject && hit.distance > Camera.main.nearClipPlane) {
    240.                 zeroParallax = hit.distance;
    241.             } else {
    242.                 //Debug.Log(trackObject.name+" is ON BUT HIDDEN");
    243.             }
    244.         }
    245.     } else {
    246.         //Debug.Log(trackObject.name+ " is OFF CAMERA");
    247.     }
    248. }
    249.  
    250. function LateUpdate() {
    251.     UpdateView();
    252. }
    253.  
    254. function UpdateView() {
    255.     switch (cameraSelect) {
    256.         case cams3D.LeftRight:
    257.             leftCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    258.             rightCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    259.             break;
    260.         case cams3D.LeftOnly:
    261.             leftCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    262.             rightCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    263.             break;
    264.         case cams3D.RightOnly:
    265.             leftCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    266.             rightCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    267.             break;
    268.         case cams3D.RightLeft:
    269.             leftCam.transform.position = transform.position + transform.TransformDirection(interaxial/2, 0, 0);
    270.             rightCam.transform.position = transform.position + transform.TransformDirection(-interaxial/2, 0, 0);
    271.             break;
    272.     }
    273.     if (cameraMethod == method3D.ToedIn) {
    274.         leftCam.camera.projectionMatrix = GetComponent.<Camera>().projectionMatrix;
    275.         rightCam.camera.projectionMatrix = GetComponent.<Camera>().projectionMatrix;
    276.         leftCam.transform.LookAt (transform.position + (transform.TransformDirection (Vector3.forward) * zeroParallax));
    277.         rightCam.transform.LookAt (transform.position + (transform.TransformDirection (Vector3.forward) * zeroParallax));
    278.     } else {
    279.         leftCam.transform.rotation = transform.rotation;
    280.         rightCam.transform.rotation = transform.rotation;
    281.         switch (cameraSelect) {
    282.             case cams3D.LeftRight:
    283.                 leftCam.camera.projectionMatrix = projectionMatrix(true);
    284.                 rightCam.camera.projectionMatrix = projectionMatrix(false);
    285.                 break;
    286.             case cams3D.LeftOnly:
    287.                 leftCam.camera.projectionMatrix = projectionMatrix(true);
    288.                 rightCam.camera.projectionMatrix = projectionMatrix(true);
    289.                 break;
    290.             case cams3D.RightOnly:
    291.                 leftCam.camera.projectionMatrix = projectionMatrix(false);
    292.                 rightCam.camera.projectionMatrix = projectionMatrix(false);
    293.                 break;
    294.             case cams3D.RightLeft:
    295.                 leftCam.camera.projectionMatrix = projectionMatrix(false);
    296.                 rightCam.camera.projectionMatrix = projectionMatrix(true);
    297.                 break;
    298.         }
    299.     }
    300. }
    301.  
    302. function OnRenderImage (source:RenderTexture, destination:RenderTexture) {
    303.    RenderTexture.active = destination;
    304.    GL.PushMatrix();
    305.    GL.LoadOrtho();
    306.    switch (format3D) {
    307.        case mode3D.Anaglyph:
    308.            stereoMaterial.SetPass(0);
    309.           DrawQuad(0);
    310.        break;
    311.        case mode3D.SideBySide:
    312.        case mode3D.OverUnder:
    313.         for(var i:int = 1; i <= 2; i++) {
    314.             stereoMaterial.SetPass(i);
    315.             DrawQuad(i);
    316.         }
    317.     break;
    318.     case mode3D.Interlace:
    319.     case mode3D.Checkerboard:
    320.         stereoMaterial.SetPass(3);
    321.         DrawQuad(3);
    322.        break;
    323.        default:
    324.        break;
    325.    }
    326.    GL.PopMatrix();
    327. }
    328.  
    329. function OnGUI () {
    330.        if (GuiVisible) {
    331.         windowRect = GUILayout.Window (0, windowRect, DoWindow, "Stereoskopix 3D Controls");
    332.         if (mouseLookScript) mouseLookScript.suppress = true;
    333.     } else {
    334.         if (mouseLookScript) mouseLookScript.suppress = false;
    335.     }
    336. }
    337.  
    338. function DoWindow (windowID : int) {
    339.     GUILayout.BeginHorizontal();
    340.         GUILayout.BeginVertical();
    341.             GUILayout.BeginHorizontal();
    342.                 GUILayout.FlexibleSpace();
    343.                 GUILayout.Label ("Mode");
    344.                 GUILayout.FlexibleSpace();
    345.             GUILayout.EndHorizontal();
    346.             format3D = GUILayout.SelectionGrid (format3D, modeStrings,1,GUILayout.MaxWidth(100));
    347.             if (GUI.changed) {
    348.                 if (format3D == mode3D.Interlace) {
    349.                     SetWeave(0);
    350.                 } else if (format3D == mode3D.Checkerboard) {
    351.                     SetWeave(1);
    352.                 }
    353.             }
    354.         GUILayout.EndVertical();
    355.         GUILayout.BeginVertical();
    356.             GUILayout.BeginHorizontal();
    357.                 GUILayout.FlexibleSpace();
    358.                 GUILayout.Label ("Options");
    359.                 GUILayout.FlexibleSpace();
    360.             GUILayout.EndHorizontal();
    361.             GUILayout.BeginHorizontal();
    362.                 GUILayout.Space(15);
    363.                 anaglyphOptions = GUILayout.Toolbar (anaglyphOptions, anaStrings,GUILayout.MaxWidth(500));
    364.                 if (GUI.changed) {
    365.                     SetAnaglyphType();
    366.                 }
    367.             GUILayout.EndHorizontal();
    368.             GUILayout.BeginHorizontal();
    369.                 GUILayout.Space(15);
    370.                 sideBySideOptions = GUILayout.Toolbar (sideBySideOptions, sbsStrings,GUILayout.MaxWidth(200));
    371.             GUILayout.EndHorizontal();
    372.             GUILayout.BeginHorizontal();
    373.                 GUILayout.FlexibleSpace();
    374.                 GUILayout.Label ("[Alt-Click on Object to Converge]");
    375.             GUILayout.EndHorizontal();
    376.             GUILayout.BeginHorizontal();
    377.                 GUILayout.Space(15);
    378.                 GUILayout.Label ("Rows",GUILayout.MinWidth(60));
    379.                 interlaceString = System.Convert.ToString(interlaceRows);
    380.                 interlaceString = GUILayout.TextField (interlaceString,4,GUILayout.MaxWidth(50));
    381.                 interlaceRows = System.Convert.ToDouble(interlaceString);
    382.                 if (GUI.changed) {
    383.                     if (format3D == mode3D.Interlace) {
    384.                         SetWeave(0);
    385.                     }
    386.                 }
    387.                 if (GUILayout.Button("-")) {
    388.                     interlaceRows -= 1;
    389.                     SetWeave(0);
    390.                 }
    391.                 if (GUILayout.Button("+")) {
    392.                     interlaceRows +=1;
    393.                     SetWeave(0);
    394.                 }        
    395.                 GUILayout.FlexibleSpace();
    396.                 toggleTrackObj = GUILayout.Toggle(toggleTrackObj, "Track Object [T]");
    397.             GUILayout.EndHorizontal();
    398.             GUILayout.BeginHorizontal();
    399.                 GUILayout.Space(15);
    400.                 GUILayout.Label ("Columns",GUILayout.MinWidth(60));
    401.                 checkerString = System.Convert.ToString(checkerboardColumns);
    402.                 checkerString = GUILayout.TextField (checkerString,4,GUILayout.MaxWidth(50));
    403.                 checkerboardColumns = System.Convert.ToDouble(checkerString);
    404.                 GUILayout.Label ("Rows");
    405.                 checkerString = System.Convert.ToString(checkerboardRows);
    406.                 checkerString = GUILayout.TextField (checkerString,4,GUILayout.MaxWidth(50));
    407.                 checkerboardRows = System.Convert.ToDouble(checkerString);
    408.                 if (GUI.changed) {
    409.                     if (format3D == mode3D.Checkerboard) {
    410.                         SetWeave(1);
    411.                     }
    412.                 }
    413.                 if (GUILayout.Button ("enter")) {
    414.                     GUI.FocusControl ("focus");
    415.                 }
    416.                 GUILayout.FlexibleSpace();
    417.                 GUILayout.Label("  ["+ToggleGuiKey+" toggles controls]");
    418.             GUILayout.EndHorizontal();
    419.         GUILayout.EndVertical();
    420.     GUILayout.EndHorizontal();
    421.     GUILayout.Space(15);
    422.     GUILayout.BeginHorizontal();
    423.             GUILayout.Label ("Camera Select",GUILayout.MinWidth(120));
    424.             GUILayout.Space(15);
    425.             cameraSelect = GUILayout.Toolbar (cameraSelect, camStrings,GUILayout.MaxWidth(400));
    426.             GUILayout.FlexibleSpace();
    427.     GUILayout.EndHorizontal();
    428.     GUILayout.BeginHorizontal();
    429.             GUILayout.Label ("Camera Method [P]",GUILayout.MinWidth(120));
    430.             GUILayout.Space(15);
    431.             cameraMethod = GUILayout.Toolbar (cameraMethod, methodStrings,GUILayout.MaxWidth(200));
    432.             GUILayout.FlexibleSpace();
    433.     GUILayout.EndHorizontal();
    434.     GUILayout.BeginHorizontal();
    435.         GUILayout.Label ("Interaxial  - +",GUILayout.MinWidth(120));
    436.         interaxial = GUILayout.HorizontalSlider (interaxial, 0.0, 5.0,GUILayout.MaxWidth(300));
    437.         GUILayout.Label (" "+interaxial);
    438.         GUILayout.FlexibleSpace();
    439.     GUILayout.EndHorizontal();
    440.     GUILayout.BeginHorizontal();
    441.         GUILayout.Label ("Zero Parallax  [ ] ",GUILayout.MinWidth(120));
    442.         zeroParallax = GUILayout.HorizontalSlider (zeroParallax, 1.0, 100.0,GUILayout.MaxWidth(300));
    443.         GUILayout.Label (" "+zeroParallax);
    444.         GUILayout.FlexibleSpace();
    445.     GUILayout.EndHorizontal();
    446.     GUILayout.BeginHorizontal();
    447.         GUILayout.Label ("Field of View",GUILayout.MinWidth(120));
    448.         fieldOfView = GUILayout.HorizontalSlider (fieldOfView, 1.0, 180.0,GUILayout.MaxWidth(300));
    449.         GetComponent.<Camera>().fieldOfView = fieldOfView;
    450.         GUILayout.Label (" "+fieldOfView);
    451.         GUILayout.FlexibleSpace();
    452.     GUILayout.EndHorizontal();
    453.     GUILayout.BeginHorizontal();
    454.         GUILayout.Label ("Aspect Ratio",GUILayout.MinWidth(120));
    455.         if (GUILayout.Button("Reset")) {
    456.             GetComponent.<Camera>().ResetAspect();
    457.             cameraAspect = GetComponent.<Camera>().aspect;
    458.         }
    459.         cameraAspect = GUILayout.HorizontalSlider (cameraAspect, 0.1, 4.0,GUILayout.MaxWidth(250));
    460.         GetComponent.<Camera>().aspect = cameraAspect;
    461.         GUILayout.Label (" "+cameraAspect);
    462.         GUILayout.FlexibleSpace();
    463.         GUI.SetNextControlName ("focus");
    464.         dummy = GUILayout.Toggle(dummy, "");
    465.  
    466.     GUILayout.EndHorizontal();
    467.     GUI.DragWindow();
    468. }
    469.  
    470. private function SetWeave(xy) {
    471.     if (xy) {
    472.         stereoMaterial.SetFloat("_Weave_X", checkerboardColumns);
    473.         stereoMaterial.SetFloat("_Weave_Y", checkerboardRows);
    474.     } else {
    475.         stereoMaterial.SetFloat("_Weave_X", 1);
    476.         stereoMaterial.SetFloat("_Weave_Y", interlaceRows);
    477.     }
    478. }
    479.  
    480. private function SetAnaglyphType() {
    481.    switch (anaglyphOptions) {
    482.            case anaType.Monochrome:
    483.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0.299,0.587,0.114,0));
    484.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    485.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    486.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    487.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0.299,0.587,0.114,0));
    488.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0.299,0.587,0.114,0));
    489.            break;
    490.            case anaType.HalfColor:
    491.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0.299,0.587,0.114,0));
    492.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    493.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    494.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    495.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,1,0,0));
    496.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0,0,1,0));
    497.            break;
    498.            case anaType.FullColor:
    499.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(1,0,0,0));
    500.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    501.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    502.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    503.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,1,0,0));
    504.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0,0,1,0));
    505.            break;
    506.            case anaType.Optimized:
    507.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0,0.7,0.3,0));
    508.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    509.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    510.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    511.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,1,0,0));
    512.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0,0,1,0));
    513.            break;
    514.            case anaType.Purple:
    515.                stereoMaterial.SetVector("_Balance_Left_R", Vector4(0.299,0.587,0.114,0));
    516.                stereoMaterial.SetVector("_Balance_Left_G", Vector4(0,0,0,0));
    517.               stereoMaterial.SetVector("_Balance_Left_B", Vector4(0,0,0,0));
    518.               stereoMaterial.SetVector("_Balance_Right_R", Vector4(0,0,0,0));
    519.               stereoMaterial.SetVector("_Balance_Right_G", Vector4(0,0,0,0));
    520.               stereoMaterial.SetVector("_Balance_Right_B", Vector4(0.299,0.587,0.114,0));
    521.            break;
    522.    }
    523. }
    524. private function DrawQuad(cam) {
    525.     if (format3D == mode3D.Anaglyph) {
    526.                GL.Begin (GL.QUADS);    
    527.               GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    528.               GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1, 0.0, 0.1 );
    529.               GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1, 1.0, 0.1 );
    530.               GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    531.                GL.End();
    532.     } else {
    533.         if (format3D==mode3D.SideBySide) {
    534.             if (cam==1) {
    535.                    GL.Begin (GL.QUADS);    
    536.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    537.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 0.5, 0.0, 0.1 );
    538.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 0.5, 1.0, 0.1 );
    539.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    540.                    GL.End();
    541.             } else {
    542.                    GL.Begin (GL.QUADS);    
    543.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.5, 0.0, 0.1 );
    544.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1.0, 0.0, 0.1 );
    545.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1.0, 1.0, 0.1 );
    546.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.5, 1.0, 0.1 );
    547.                    GL.End();
    548.             }
    549.         } else if (format3D == mode3D.OverUnder) {
    550.             if (cam==1) {
    551.                    GL.Begin (GL.QUADS);    
    552.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.5, 0.1 );
    553.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1.0, 0.5, 0.1 );
    554.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1.0, 1.0, 0.1 );
    555.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    556.                    GL.End();
    557.             } else {
    558.                    GL.Begin (GL.QUADS);    
    559.                   GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    560.                   GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1.0, 0.0, 0.1 );
    561.                   GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1.0, 0.5, 0.1 );
    562.                   GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 0.5, 0.1 );
    563.                    GL.End();
    564.             }
    565.         } else if (format3D == mode3D.Interlace || format3D == mode3D.Checkerboard) {
    566.                GL.Begin (GL.QUADS);    
    567.               GL.TexCoord2( 0.0, 0.0 ); GL.Vertex3( 0.0, 0.0, 0.1 );
    568.               GL.TexCoord2( 1.0, 0.0 ); GL.Vertex3( 1, 0.0, 0.1 );
    569.               GL.TexCoord2( 1.0, 1.0 ); GL.Vertex3( 1, 1.0, 0.1 );
    570.               GL.TexCoord2( 0.0, 1.0 ); GL.Vertex3( 0.0, 1.0, 0.1 );
    571.                GL.End();
    572.         }
    573.     }
    574. }
    575.  
    576. function PerspectiveOffCenter(
    577.     left : float, right : float,
    578.     bottom : float, top : float,
    579.     near : float, far : float ) : Matrix4x4 {      
    580.     var x =  (2.0 * near) / (right - left);
    581.     var y =  (2.0 * near) / (top - bottom);
    582.     var a =  (right + left) / (right - left);
    583.     var b =  (top + bottom) / (top - bottom);
    584.     var c = -(far + near) / (far - near);
    585.     var d = -(2.0 * far * near) / (far - near);
    586.     var e = -1.0;
    587.  
    588.     var m : Matrix4x4;
    589.     m[0,0] = x;  m[0,1] = 0;  m[0,2] = a;  m[0,3] = 0;
    590.     m[1,0] = 0;  m[1,1] = y;  m[1,2] = b;  m[1,3] = 0;
    591.     m[2,0] = 0;  m[2,1] = 0;  m[2,2] = c;  m[2,3] = d;
    592.     m[3,0] = 0;  m[3,1] = 0;  m[3,2] = e;  m[3,3] = 0;
    593.     return m;
    594. }
    595.  
    596. function projectionMatrix(isLeftCam : boolean) : Matrix4x4 {
    597.    var left : float;
    598.    var right : float;
    599.    var a : float;
    600.    var b : float;
    601.    var FOVrad : float;
    602.    var aspect: float = GetComponent.<Camera>().aspect;
    603.    var tempAspect: float;
    604.    if (sideBySideOptions == modeSBS.Unsqueezed && format3D == mode3D.SideBySide) {
    605.            FOVrad = GetComponent.<Camera>().fieldOfView / 90.0 * Mathf.PI;
    606.            tempAspect = aspect/2;
    607.    } else {
    608.            FOVrad = GetComponent.<Camera>().fieldOfView / 180.0 * Mathf.PI;
    609.            tempAspect = aspect;
    610.    }
    611.    a = GetComponent.<Camera>().nearClipPlane * Mathf.Tan(FOVrad * 0.5);
    612.    b = GetComponent.<Camera>().nearClipPlane / (zeroParallax + GetComponent.<Camera>().nearClipPlane);
    613.  
    614.    if (isLeftCam) {
    615.       left  = - tempAspect * a + (interaxial/2) * b;
    616.       right =   tempAspect * a + (interaxial/2) * b;
    617.    }
    618.    else {
    619.       left  = - tempAspect * a - (interaxial/2) * b;
    620.       right =   tempAspect * a - (interaxial/2) * b;
    621.    }
    622.  
    623.    return PerspectiveOffCenter(left, right, -a, a, GetComponent.<Camera>().nearClipPlane, GetComponent.<Camera>().farClipPlane);
    624.    
    625. }

    Did someone test it on Unity5?
     
  29. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,091
    necro bump here but @DeWol do you have by any chance / do you share the sourcecode of your plugin?
     
  30. Vital-Volkov

    Vital-Volkov

    Joined:
    Mar 30, 2015
    Posts:
    4
    3 years ago I made the post, and submit the clean source code to the asset store. But the Unity team asked me for a demo and declined. I planned to resubmit it in the future. ;)
     
    Last edited: Jan 7, 2021
    jmunozar likes this.
  31. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    Another bump:
    The asset's down now unfortunately. Can you still get stereo 3D (with a 3D vision monitor + vision 2 glasses) to work somehow with Unity 2017?

    @WitalSimulations Any news about your asset?
     
  32. Vital-Volkov

    Vital-Volkov

    Joined:
    Mar 30, 2015
    Posts:
    4
    Ok, finally, I made and polish my stereoscopic 3D settings system and decided to publish it for all on GitHub - https://github.com/Vital-Volkov/Stereoscopic-3D-system-for-Unity-2019-

    https://forum.unity.com/threads/ste...er-post-processing-stack-v2-urp-hdrp.1034611/
     
    Thanathos likes this.