├── Assets ├── LQ.jpg ├── FakeAR.unity ├── ShaderMaterial.mat ├── Standard Assets │ ├── Effects │ │ ├── ImageEffects │ │ │ ├── Shaders │ │ │ │ ├── FisheyeShader.shader.meta │ │ │ │ └── FisheyeShader.shader │ │ │ └── Shaders.meta │ │ └── ImageEffects.meta │ ├── Effects.meta │ ├── Utility.meta │ └── Utility │ │ ├── FPSCounter.cs.meta │ │ └── FPSCounter.cs ├── FakeAR.unity.meta ├── ShaderMaterial.mat.meta ├── Standard Assets.meta ├── FakeARShader.shader.meta ├── AndroidWebcamDisplay.cs.meta ├── LQ.jpg.meta ├── FakeARShader.shader └── AndroidWebcamDisplay.cs ├── ProjectSettings ├── ProjectVersion.txt ├── TagManager.asset ├── AudioManager.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── TimeManager.asset ├── DynamicsManager.asset ├── EditorSettings.asset ├── NetworkManager.asset ├── ProjectSettings.asset ├── QualitySettings.asset ├── GraphicsSettings.asset ├── Physics2DSettings.asset ├── UnityAdsSettings.asset ├── ClusterInputManager.asset ├── EditorBuildSettings.asset └── UnityConnectSettings.asset ├── capture_with_disparity.png ├── capture_without_disparity.png ├── .gitignore └── README.MD /Assets/LQ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/Assets/LQ.jpg -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.4.1f1 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /Assets/FakeAR.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/Assets/FakeAR.unity -------------------------------------------------------------------------------- /Assets/ShaderMaterial.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/Assets/ShaderMaterial.mat -------------------------------------------------------------------------------- /capture_with_disparity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/capture_with_disparity.png -------------------------------------------------------------------------------- /capture_without_disparity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/capture_without_disparity.png -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityAdsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/UnityAdsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian256/cardboard_seethrough/HEAD/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /Assets/Standard Assets/Effects/ImageEffects/Shaders/FisheyeShader.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 874ceab4425f64bccb1d14032f4452b1 3 | ShaderImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Effects.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 115d1f9d9bd29064ab981e57c8fc8cdf 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | assetBundleName: 7 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Effects/ImageEffects.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6e0c95a128e14227939c51b5d9ad74e 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | assetBundleName: 7 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Effects/ImageEffects/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2145489f7c704db8acb14a52bddeee9 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | assetBundleName: 7 | -------------------------------------------------------------------------------- /Assets/FakeAR.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8dbfa92dd39bc104d9b199559ed93dcb 3 | timeCreated: 1476460359 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/ShaderMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f45ae7453299f344bae3ab4560791419 3 | timeCreated: 1476460362 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb65df16bb702a0499a50bada9301a5e 3 | folderAsset: yes 4 | timeCreated: 1476460359 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/FakeARShader.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f056997571629e5409c300faafa6ae57 3 | timeCreated: 1476460362 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Utility.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3dfb62025f3a2544eb7e8816d8778f80 3 | folderAsset: yes 4 | timeCreated: 1476460359 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/AndroidWebcamDisplay.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f7553402d7cad141bd57e7afc52aa09 3 | timeCreated: 1476460360 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Utility/FPSCounter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a635c66c16d44d44291bda56ce326511 3 | timeCreated: 1476460360 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Autogenerated VS/MD/Consulo solution and project files 9 | ExportedObj/ 10 | .consulo/ 11 | *.csproj 12 | *.unityproj 13 | *.sln 14 | *.suo 15 | *.tmp 16 | *.user 17 | *.userprefs 18 | *.pidb 19 | *.booproj 20 | *.svd 21 | 22 | 23 | # Unity3D generated meta files 24 | *.pidb.meta 25 | 26 | # Unity3D Generated File On Crash Reports 27 | sysinfo.txt 28 | 29 | # Builds 30 | *.apk 31 | *.unitypackage -------------------------------------------------------------------------------- /Assets/Standard Assets/Utility/FPSCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | namespace UnityStandardAssets.Utility 6 | { 7 | [RequireComponent(typeof (Text))] 8 | public class FPSCounter : MonoBehaviour 9 | { 10 | const float fpsMeasurePeriod = 0.5f; 11 | private int m_FpsAccumulator = 0; 12 | private float m_FpsNextPeriod = 0; 13 | private int m_CurrentFps; 14 | const string display = "{0} FPS"; 15 | private Text m_Text; 16 | 17 | 18 | private void Start() 19 | { 20 | m_FpsNextPeriod = Time.realtimeSinceStartup + fpsMeasurePeriod; 21 | m_Text = GetComponent(); 22 | } 23 | 24 | 25 | private void Update() 26 | { 27 | // measure average frames per second 28 | m_FpsAccumulator++; 29 | if (Time.realtimeSinceStartup > m_FpsNextPeriod) 30 | { 31 | m_CurrentFps = (int) (m_FpsAccumulator/fpsMeasurePeriod); 32 | m_FpsAccumulator = 0; 33 | m_FpsNextPeriod += fpsMeasurePeriod; 34 | m_Text.text = string.Format(display, m_CurrentFps); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Effects/ImageEffects/Shaders/FisheyeShader.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/FisheyeShader" { 2 | Properties { 3 | _MainTex ("Base (RGB)", 2D) = "" {} 4 | } 5 | 6 | // Shader code pasted into all further CGPROGRAM blocks 7 | CGINCLUDE 8 | 9 | #include "UnityCG.cginc" 10 | 11 | struct v2f { 12 | float4 pos : SV_POSITION; 13 | float2 uv : TEXCOORD0; 14 | }; 15 | 16 | sampler2D _MainTex; 17 | 18 | float2 intensity; 19 | 20 | v2f vert( appdata_img v ) 21 | { 22 | v2f o; 23 | o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 24 | o.uv = v.texcoord.xy; 25 | return o; 26 | } 27 | 28 | half4 frag(v2f i) : SV_Target 29 | { 30 | half2 coords = i.uv; 31 | coords = (coords - 0.5) * 2.0; 32 | 33 | half2 realCoordOffs; 34 | realCoordOffs.x = (1-coords.y * coords.y) * intensity.y * (coords.x); 35 | realCoordOffs.y = (1-coords.x * coords.x) * intensity.x * (coords.y); 36 | 37 | half4 color = tex2D (_MainTex, i.uv - realCoordOffs); 38 | 39 | return color; 40 | } 41 | 42 | ENDCG 43 | 44 | Subshader { 45 | Pass { 46 | ZTest Always Cull Off ZWrite Off 47 | 48 | CGPROGRAM 49 | #pragma vertex vert 50 | #pragma fragment frag 51 | ENDCG 52 | } 53 | 54 | } 55 | 56 | Fallback off 57 | 58 | } // shader 59 | -------------------------------------------------------------------------------- /Assets/LQ.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 89dee53eb663af64eb988001aa58c826 3 | timeCreated: 1476460362 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | spriteTessellationDetail: -1 50 | textureType: -1 51 | buildTargetSettings: [] 52 | spriteSheet: 53 | serializedVersion: 2 54 | sprites: [] 55 | outline: [] 56 | spritePackingTag: 57 | userData: 58 | assetBundleName: 59 | assetBundleVariant: 60 | -------------------------------------------------------------------------------- /Assets/FakeARShader.shader: -------------------------------------------------------------------------------- 1 | // Author: Long Qian 2 | // Email: lqian8@jhu.edu 3 | 4 | Shader "Custom/FakeAR" 5 | { 6 | Properties{ 7 | _MainTex("", 2D) = "white" {} 8 | [HideInInspector]_FOV("FOV", Range(1, 2)) = 1.6 9 | [HideInInspector]_Disparity("Disparity", Range(0, 0.3)) = 0.1 10 | [HideInInspector]_Alpha("Alpha", Range(0, 2.0)) = 1.0 11 | } 12 | 13 | SubShader{ 14 | 15 | Pass{ 16 | CGPROGRAM 17 | #pragma vertex vert 18 | #pragma fragment frag 19 | #include "UnityCG.cginc" 20 | 21 | struct v2f { 22 | float4 pos : POSITION; 23 | float2 uv : TEXCOORD0; 24 | }; 25 | 26 | // Default Vertex Shader 27 | v2f vert(appdata_img v) { 28 | v2f o; 29 | o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 30 | o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord.xy); 31 | return o; 32 | } 33 | 34 | // Parameters 35 | sampler2D _MainTex; 36 | float _FOV; 37 | 38 | // Alpha is the ratio of pixel density: width to height 39 | float _Alpha; 40 | // Disparity is the portion to separate 41 | // larger disparity cause closer stereovision 42 | float _Disparity; 43 | 44 | 45 | // Fragment Shader: Remap the texture coordinates to combine 46 | // barrel distortion and disparity video display 47 | fixed4 frag(v2f i) : COLOR { 48 | float2 uv1, uv2, uv3; 49 | float t1, t2; 50 | float offset; 51 | 52 | // uv1 is the remap of left and right screen to a full screen 53 | uv1 = i.uv - 0.5; 54 | uv1.x = uv1.x * 2 - 0.5 + sign(i.uv.x < 0.5); 55 | 56 | t1 = sqrt(1.0 - uv1.x * uv1.x - uv1.y * uv1.y); 57 | t2 = 1.0 / (t1 * tan(_FOV * 0.5)); 58 | 59 | // uv2 is the remap of side screen with barrel distortion 60 | uv2 = uv1 * t2 + 0.5; 61 | 62 | // black color for out-of-range pixels 63 | if (uv2.x >= 1 || uv2.y >= 1 || uv2.x <= 0 || uv2.y <= 0) { 64 | return fixed4(0, 0, 0, 1); 65 | } 66 | else { 67 | offset = 0.5 - _Alpha * 0.5 + _Disparity * 0.5 - _Disparity * sign(i.uv.x < 0.5); 68 | // uv3 is the remap of image texture 69 | uv3 = uv2; 70 | uv3.x = uv2.x * _Alpha + offset; 71 | return tex2D(_MainTex, uv3); 72 | } 73 | } 74 | ENDCG 75 | } 76 | } 77 | FallBack "Diffuse" 78 | } 79 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | Cardboard See-Through 2 | === 3 | Author: [Long Qian](http://longqian.me/aboutme) 4 | 5 | Date: 2016-10-14 6 | 7 | ## Overview 8 | The purpose of this repository is to turn Google Cardboard into an **Video See-Through (VST) Augmented Reality device**. However, there is usually only one camera for iOS and Android devices. The stereo vision is simulated by applying a fixed disparity to the left half and right half of the screen. [iPhone 7](http://www.apple.com/iphone-7/specs/) plus does have two cameras, but unfortuantely, they are not aligned vertically. The detailed post can be found on this [blog](http://longqian.me/2016/10/16/google-cardboard-as-augmented-reality-headset/) page. 9 | 10 | ## Requirement 11 | ### Building 12 | * Unity3D (v5.0+) 13 | * Android SDK 14 | 15 | ### Running 16 | * Android Phone (API 19+) 17 | * **Google Cardboard v1**: Cardboard v2 is great, but it does not support camera capture. 18 | 19 | ## Implementation 20 | **Fragment shader** (pixel shader) of Unity3D does almost everything here, including: 21 | 22 | * Apply correct pixel density adjustment to display image with correct scale 23 | * [Barrel distortion](https://en.wikipedia.org/wiki/Distortion_(optics)) is done, so that the image is good for Cardboard lenses. 24 | * Put disparity to the two halves of the display, so that a **FAKE** stereo vision is created. 25 | 26 | The **FOV** and **disparity** level can be adjust through sliders on screen. **Frame rate** is displayed as well. 27 | 28 | The pixel moving job is the last step of rendering. Augmented Reality application can run over this implementation, before the final texture is blited to the screen. 29 | 30 | ## Demonstration 31 | * The slider on the top right corner controls the field of view, which is correspondent to the size of visible area on the screen 32 | * The slider on the button right corner controls the percentage of the difference in the image 33 | * 0.0 for exactly same display 34 | * 0.1 for 10% difference (0.3 maximum). 35 | 36 | ![capture](capture_with_disparity.png "Capture with disparity") 37 | 38 | ![capture](capture_without_disparity.png "Capture without disparity") 39 | 40 | ## Conclusion 41 | * **Shader** is your best friend. 42 | * I am looking forward to stereo vision cameras on Android platforms. 43 | 44 | 45 | -------------------------------------------------------------------------------- /Assets/AndroidWebcamDisplay.cs: -------------------------------------------------------------------------------- 1 | // Author: Long Qian 2 | // Email: lqian8@jhu.edu 3 | 4 | using UnityEngine; 5 | using System.Collections; 6 | 7 | public class AndroidWebcamDisplay : MonoBehaviour { 8 | 9 | private WebCamTexture webCameraTexture; 10 | 11 | // save the webcam texture 12 | private Material camTextureHolder; 13 | 14 | // shader of implementing fake AR effect 15 | public Material shaderMaterial; 16 | 17 | // backup image 18 | public Texture backupImage; 19 | 20 | // a null RenderTexture object to hold place in Graphics.Blit function 21 | private RenderTexture nullRenderTexture = null; 22 | 23 | // width and height of actual webcam texture 24 | private int webcamWidth, webcamHeight; 25 | 26 | // fps counter 27 | const float fpsMeasurePeriod = 0.5f; 28 | private int m_FpsAccumulator = 0; 29 | private float m_FpsNextPeriod = 0; 30 | private int m_CurrentFps; 31 | private int fontSize = 40; 32 | 33 | [Range(1.0f, 2.0f)] 34 | public float FOV = 1.6f; 35 | [Range(0.0f, 0.3f)] 36 | public float Disparity = 0.1f; 37 | 38 | 39 | // Use this for initialization 40 | void Start() { 41 | 42 | // Never turn off the screen 43 | Screen.sleepTimeout = SleepTimeout.NeverSleep; 44 | 45 | m_FpsNextPeriod = Time.realtimeSinceStartup + fpsMeasurePeriod; 46 | 47 | Debug.Log("Screen width = " + Screen.width + ", height = " + Screen.height); 48 | 49 | // camTextureHolder needs to be initialized before using 50 | camTextureHolder = new Material(shaderMaterial); 51 | 52 | // Checks how many and which cameras are available on the device 53 | for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) { 54 | 55 | #if UNITY_EDITOR 56 | // In editor mode, the camera is usually front facing 57 | // grab any camera is fine for testing 58 | webCameraTexture = new WebCamTexture(cameraIndex, Screen.width * 10, Screen.height * 10); 59 | #endif 60 | // grab the back facing camera on Android device 61 | if (!WebCamTexture.devices[cameraIndex].isFrontFacing) { 62 | webCameraTexture = new WebCamTexture(cameraIndex, Screen.width, Screen.height); 63 | } 64 | 65 | } 66 | 67 | camTextureHolder.mainTexture = webCameraTexture; 68 | webCameraTexture.Play(); 69 | 70 | webcamWidth = webCameraTexture.width; 71 | webcamHeight = webCameraTexture.height; 72 | 73 | Debug.Log("WebcamTexture width = " + webcamWidth + ", height = " + webcamHeight); 74 | 75 | // Alpha is the pixel density ration of width over height 76 | // Needed for displaying the final image without skew 77 | float Alpha = (float)webcamHeight / (float)Screen.height * (float)Screen.width * 0.5f / (float)webcamWidth; 78 | shaderMaterial.SetFloat("_Alpha", Alpha); 79 | 80 | Debug.Log("Alpha value of Shader set to: " + Alpha); 81 | } 82 | 83 | 84 | public void ShowCamera() { 85 | //myCameraTexture.GetComponent().enabled = true; 86 | webCameraTexture.Play(); 87 | } 88 | 89 | public void HideCamera() { 90 | 91 | // myCameraTexture.GetComponent().enabled = false; 92 | webCameraTexture.Stop(); 93 | } 94 | 95 | void OnGUI() { 96 | int labelHeight = 40; 97 | int boundary = 20; 98 | GUI.skin.label.fontSize = GUI.skin.box.fontSize = GUI.skin.button.fontSize = fontSize; 99 | // A button to demonstrate how to turn the camera on and off, in case you need it 100 | if (GUI.Button(new Rect(0, 0, 200, 60), "ON/OFF")) { 101 | if (webCameraTexture.isPlaying) 102 | this.HideCamera(); 103 | else 104 | this.ShowCamera(); 105 | } 106 | GUI.skin.label.alignment = TextAnchor.MiddleLeft; 107 | GUI.Label(new Rect(boundary, Screen.height - boundary - labelHeight, 400, labelHeight), webcamWidth + " x " + webcamHeight + " " + m_CurrentFps + "fps"); 108 | 109 | GUI.Label(new Rect(Screen.width - boundary - 200, boundary, 200, labelHeight), "FOV"); 110 | FOV = GUI.HorizontalSlider(new Rect(Screen.width - boundary - 200, boundary + labelHeight, 200, labelHeight), FOV, 1.0F, 2.0F); 111 | shaderMaterial.SetFloat("_FOV", FOV); 112 | 113 | GUI.Label(new Rect(Screen.width - boundary - 200, Screen.height - labelHeight * 2 - boundary, 200, labelHeight), "Disparity"); 114 | Disparity = GUI.HorizontalSlider(new Rect(Screen.width - boundary - 200, Screen.height - labelHeight - boundary, 200, labelHeight), Disparity, 0.0F, 0.3F); 115 | shaderMaterial.SetFloat("_Disparity", Disparity); 116 | } 117 | 118 | // Update is called once per frame 119 | void Update() { 120 | ; 121 | 122 | } 123 | 124 | void OnRenderImage(RenderTexture src, RenderTexture dest) { 125 | // shaderMaterial renders the image with Barrel distortion and disparity effect 126 | Graphics.Blit(camTextureHolder.mainTexture, nullRenderTexture, shaderMaterial); 127 | 128 | // measure average frames per second 129 | m_FpsAccumulator++; 130 | if (Time.realtimeSinceStartup > m_FpsNextPeriod) { 131 | m_CurrentFps = (int)(m_FpsAccumulator / fpsMeasurePeriod); 132 | m_FpsAccumulator = 0; 133 | m_FpsNextPeriod += fpsMeasurePeriod; 134 | } 135 | } 136 | 137 | } 138 | --------------------------------------------------------------------------------