Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  4. Build games and experiences that can load instantly and without install. Explore the Project Tiny Preview today!
    Dismiss Notice
  5. Nominations have been announced for this years Unity Awards. Celebrate the wonderful projects made by your peers this year and get voting! Vote here!
    Dismiss Notice
  6. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    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:
    184
    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:
    525
    great help man.
     
  4. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    525
    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,460
    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:
    525
    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:
    161
    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:
    161
    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:
    525

    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:
    525
    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:
    525

    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. WitalSimulations

    WitalSimulations

    Joined:
    Mar 30, 2015
    Posts:
    3
    Hello.
    Long time I using drivers like IZ3D and DDD(tridef) but not satisfied their realisation of stereo 3D settings. It's hard to achieve realistic stereo 3D with them because when need only two main clear settings there complex settings with not obvious units and logic settings. I'm wanted make my own realisation of stereo 3D like it should be and Unity give me this possibility and thank you guys who made stereoskopix. I remade it and result you can see in my Demo Island -

    http://www.mediafire.com/download/0pwba92oj6z3sp3/DeWol_S3D_Demo.zip

    DeWolS3D_Demo_Island2.png

    Futures:
    1) Only 2 main values input for full realistic stereo 3D, other settings automatic but can be manual.
    2) Separate cameras IPD easy allow to see VR like gigant looking on toy and vise versa. Better than:
    wpid-Rl1gloeu5xY.jpg
    3) Correct Zooming vertical and horizontal field of view from 0.1 to 179.9 absolute real degrees angle.
    4) Screen distance(projector) easy allow match real and virtual FOV and get absolute real view. Most
    actual for HMD's with 360 free head tracking like Oculus Rift etc.
    5) Optimized half resolution render for specific stereo 3D methods.
    6) Vertical row shift for horizontal interleaved method give 100% edges match without optimized resolution.
    7) Absolute clear render textures with point filter without antialiasing.
    8) Render texture antialiasing in forward lighting and native antialiasing while stereo 3D disabled, post process antialiasing in deffered lighting.
    9) Non symmetric cameras IPD if required. Actual for choose left or right eye use for aiming via optics in VR.
    10) Non symmetric images shift if required.
    And more...

    Also detailed explanation in russian how 3D stereo works - http://www.avsim.su/forum/topic/137734-пора-переходить-на-стерео-3d

    Also added virtual-to-real connection using TrackIR plugin from https://github.com/byBrick/Unity-TrackIR-Plugin (thanks to tboogh):

    Futures:
    1) Free head roll in stereo 3D.
    2) Free move relative screen x,y,z and VR respond to real moving 1:1.
    And more...
     
    Last edited: Apr 18, 2015
    bjonreyes likes this.
  30. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,058
    necro bump here but @DeWol do you have by any chance / do you share the sourcecode of your plugin?
     
  31. WitalSimulations

    WitalSimulations

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

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    101
    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?
     
  33. WitalSimulations

    WitalSimulations

    Joined:
    Mar 30, 2015
    Posts:
    3
    Wich asset down? Do you need using "3D vision" active glasses with Unity 2017 and can't find right asset?

    I'm not using active S3D, "3D vision" have the option "Optimized for GeForce" to output passive S3D with "compatible" monitors - Zalman and Acer. I have installed Zalman driver for my LG D2342P monitor and using "3D vision" as passive S3D for games without native S3D.
    I simplify settings for my S3D system and now it looks like this:
    WS_S3D.png
    It's not using any drivers. Unity now has support for S3D rendering, I will check how it can be used.
    But S3D screens now out of the market, I can't buy new S3D TV or monitor now. LG "cinema 3D" was best S3D on screens, the last TV on market is OLED S3D in 2016. The last thing is using projector with silver screen and polarized light without loss resolution instead of self-illuminated screens with a polarized film on top of screen and loss in resolution as result. I always play games in S3D since I bought my monitor in 2011 and as I understand very rare people are using S3D.
     
    Last edited: Dec 6, 2018