123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- namespace RenderHeads.Media.AVProMovieCapture
- {
-
-
-
-
- [AddComponentMenu("AVPro Movie Capture/Capture From Camera 360 Stereo ODS (VR)", 101)]
- public class CaptureFromCamera360ODS : CaptureBase
- {
- [System.Serializable]
- public class Settings
- {
- [SerializeField]
- public Camera camera = null;
- [SerializeField]
- public CameraSelector cameraSelector = null;
- [SerializeField]
- [Tooltip("Render 180 degree equirectangular instead of 360 degrees. Also faster rendering")]
- public bool render180Degrees = false;
- [SerializeField]
- [Tooltip("Makes assumption that 1 Unity unit is 1m")]
- public float ipd = 0.064f;
- [SerializeField]
- [Tooltip("Higher value meant less slices to render, but can affect quality.")]
- public int pixelSliceSize = 1;
- [SerializeField]
- [Range(1, 31)]
- [Tooltip("May need to be increased to work with some post image effects. Value is in pixels.")]
- public int paddingSize = 1;
- [SerializeField]
- public CameraClearFlags cameraClearMode = CameraClearFlags.Color;
- [SerializeField]
- public Color cameraClearColor = Color.black;
- [SerializeField]
- public Behaviour[] cameraImageEffects = null;
- }
- [SerializeField] Settings _settings = new Settings();
- public Settings Setup
- {
- get { return _settings; }
- }
-
- private int _eyeWidth = 1920;
- private int _eyeHeight = 1080;
- private Transform _cameraGroup;
- private Camera _leftCameraTop;
- private Camera _leftCameraBot;
- private Camera _rightCameraTop;
- private Camera _rightCameraBot;
- private RenderTexture _final;
- private System.IntPtr _targetNativePointer = System.IntPtr.Zero;
- private Material _finalMaterial;
- private int _propSliceCenter;
- public CaptureFromCamera360ODS()
- {
-
- this.IsRealTime = false;
- _renderResolution = Resolution.POW2_4096x4096;
-
- }
- public void SetCamera(Camera camera)
- {
- _settings.camera = camera;
-
- }
- public override void Start()
- {
- Shader mergeShader = Shader.Find("Hidden/AVProMovieCapture/ODSMerge");
- if (mergeShader != null)
- {
- _finalMaterial = new Material(mergeShader);
- }
- else
- {
- Debug.LogError("[AVProMovieCapture] Can't find Hidden/AVProMovieCapture/ODSMerge shader");
- }
- _propSliceCenter = Shader.PropertyToID("_sliceCenter");
- base.Start();
- }
- private Camera CreateEye(Camera camera, string gameObjectName, float yRot, float xOffset, int cameraTargetHeight, int cullingMask, float fov, float aspect, int aalevel)
- {
- bool isCreated = false;
- if (camera == null)
- {
- GameObject eye = new GameObject(gameObjectName);
- eye.transform.parent = _cameraGroup;
- eye.transform.rotation = Quaternion.AngleAxis(-yRot, Vector3.right);
- eye.transform.localPosition = new Vector3(xOffset, 0f, 0f);
-
-
- eye.hideFlags = this.gameObject.hideFlags;
- camera = eye.AddComponent<Camera>();
- isCreated = true;
- }
- camera.fieldOfView = fov;
- camera.aspect = aspect;
- camera.clearFlags = _settings.cameraClearMode;
- camera.backgroundColor = _settings.cameraClearColor;
- camera.cullingMask = cullingMask;
- camera.useOcclusionCulling = false;
- camera.renderingPath = _settings.camera.renderingPath;
- camera.nearClipPlane = _settings.camera.nearClipPlane;
- camera.farClipPlane = _settings.camera.farClipPlane;
- #if UNITY_5_6_OR_NEWER
- camera.allowHDR = _settings.camera.allowHDR;
- camera.allowMSAA = _settings.camera.allowMSAA;
- if (camera.renderingPath == RenderingPath.DeferredShading
- #if AVPRO_MOVIECAPTURE_DEFERREDSHADING
- || camera.renderingPath == RenderingPath.DeferredLighting
- #endif
- )
- {
- camera.allowMSAA = false;
- }
- #endif
- {
- int textureWidth = _settings.pixelSliceSize + 2 * _settings.paddingSize;
- int textureHeight = cameraTargetHeight;
- if (camera.targetTexture != null)
- {
- camera.targetTexture.DiscardContents();
- if (camera.targetTexture.width != textureWidth || camera.targetTexture.height != textureHeight || camera.targetTexture.antiAliasing != aalevel)
- {
- RenderTexture.ReleaseTemporary(camera.targetTexture);
- camera.targetTexture = null;
- }
- }
- if (camera.targetTexture == null)
- {
- camera.targetTexture = RenderTexture.GetTemporary(textureWidth, textureHeight, 24, RenderTextureFormat.Default, RenderTextureReadWrite.Default, aalevel);
- }
- }
-
- camera.enabled = false;
-
- if (isCreated)
- {
-
- if (_settings.cameraImageEffects != null)
- {
- for (int i = 0; i < _settings.cameraImageEffects.Length; i++)
- {
- Behaviour origComponent = _settings.cameraImageEffects[i];
- if (origComponent != null)
- {
- if (origComponent.enabled)
- {
- #if UNITY_EDITOR
- Behaviour newComponent = (Behaviour)camera.gameObject.AddComponent(origComponent.GetType());
-
- UnityEditor.EditorUtility.CopySerialized(origComponent, newComponent);
-
- newComponent.enabled = false;
- newComponent.enabled = true;
- #endif
- }
- }
- else
- {
- Debug.LogWarning("[AVProMovieCapture] Image effect is null");
- }
- }
- }
- }
- return camera;
- }
- public override void UpdateFrame()
- {
- if (_settings.cameraSelector != null)
- {
- if (_settings.camera != _settings.cameraSelector.Camera)
- {
- SetCamera(_settings.cameraSelector.Camera);
- }
- }
- if (_useWaitForEndOfFrame)
- {
- if (_capturing && !_paused)
- {
- StartCoroutine(FinalRenderCapture());
- }
- }
- else
- {
- Capture();
- }
- base.UpdateFrame();
- }
- private IEnumerator FinalRenderCapture()
- {
- yield return _waitForEndOfFrame;
- Capture();
- }
- private void Capture()
- {
- TickFrameTimer();
- AccumulateMotionBlur();
- if (_capturing && !_paused)
- {
- if (_settings.camera != null && _handle >= 0)
- {
- bool canGrab = true;
- if (IsUsingMotionBlur())
- {
-
- canGrab = _motionBlur.IsFrameAccumulated;
- }
- if (canGrab && CanOutputFrame())
- {
-
- RenderTexture finalTexture = null;
- if (!IsUsingMotionBlur())
- {
- RenderFrame();
- finalTexture = _final;
- }
- else
- {
- finalTexture = _motionBlur.FinalTexture;
- }
-
- RenderTexture newSourceTexture = UpdateForSideBySideTransparency( finalTexture );
- if (newSourceTexture)
- {
- finalTexture = newSourceTexture;
- }
- if (_targetNativePointer == System.IntPtr.Zero || _supportTextureRecreate)
- {
-
-
- _targetNativePointer = finalTexture.GetNativeTexturePtr();
- }
- NativePlugin.SetTexturePointer(_handle, _targetNativePointer);
- RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer);
- GL.InvalidateState();
- UpdateFPS();
- }
- }
- }
- RenormTimer();
- }
- private void AccumulateMotionBlur()
- {
- if (_motionBlur != null)
- {
- if (_capturing && !_paused)
- {
- if (_settings.camera != null && _handle >= 0)
- {
- RenderFrame();
- _motionBlur.Accumulate(_final);
- }
- }
- }
- }
- private void RenderFrame()
- {
- _cameraGroup.position = _settings.camera.transform.position;
- Quaternion originalRot = _settings.camera.transform.rotation * Quaternion.AngleAxis(180f, Vector3.up);
- float rotationStep = 360f / _eyeWidth;
- int startPixelX = 0;
- int maxPixelX = _eyeWidth / _settings.pixelSliceSize;
- int endPixelX = maxPixelX;
- if (_settings.render180Degrees)
- {
-
- startPixelX = endPixelX / 4;
- endPixelX -= startPixelX;
-
- startPixelX = Mathf.Max(0, startPixelX - 2);
- endPixelX = Mathf.Min(maxPixelX, endPixelX + 2);
- }
- _final.DiscardContents();
- for (int i = startPixelX; i < endPixelX; ++i)
- {
- int step = i * _settings.pixelSliceSize;
- float v = step * rotationStep;
- _cameraGroup.rotation = originalRot * Quaternion.AngleAxis(v, Vector3.up);
- _leftCameraTop.targetTexture.DiscardContents();
- _leftCameraBot.targetTexture.DiscardContents();
- _rightCameraTop.targetTexture.DiscardContents();
- _rightCameraBot.targetTexture.DiscardContents();
- _leftCameraTop.Render();
- _leftCameraBot.Render();
- _rightCameraTop.Render();
- _rightCameraBot.Render();
- _finalMaterial.SetFloat(_propSliceCenter, step + _settings.pixelSliceSize / 2f);
- Graphics.Blit(null, _final, _finalMaterial);
-
- }
- }
- public override Texture GetPreviewTexture()
- {
- if (IsUsingMotionBlur())
- {
- return _motionBlur.FinalTexture;
- }
- return _final;
- }
- public override bool PrepareCapture()
- {
- if (_capturing)
- {
- return false;
- }
- #if UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN)
- if (SystemInfo.graphicsDeviceVersion.StartsWith("Direct3D 9"))
- {
- Debug.LogError("[AVProMovieCapture] Direct3D9 not yet supported, please use Direct3D11 instead.");
- return false;
- }
- else if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL") && !SystemInfo.graphicsDeviceVersion.Contains("emulated"))
- {
- Debug.LogError("[AVProMovieCapture] OpenGL not yet supported for CaptureFromCamera360ODS component, please use Direct3D11 instead. You may need to switch your build platform to Windows.");
- return false;
- }
- #endif
-
- if (UnityEngine.Profiling.Profiler.enabled)
- {
- Debug.LogWarning("[AVProMovieCapture] Having the Unity profiler enabled while using the CaptureFromCamera360ODS component is not recommended. Too many samples are generated which can make the system run out of memory. Disable the profiler, close the window and remove the tab. A Unity restart may be required after disabling the profiler recording");
- }
-
- _pixelFormat = NativePlugin.PixelFormat.RGBA32;
- _isTopDown = true;
- if (_settings.cameraSelector != null)
- {
- if (_settings.camera != _settings.cameraSelector.Camera)
- {
- SetCamera(_settings.cameraSelector.Camera);
- }
- }
- if (_settings.camera == null)
- {
- SetCamera(this.GetComponent<Camera>());
- }
- if (_settings.camera == null)
- {
- Debug.LogError("[AVProMovieCapture] No camera assigned to CaptureFromCamera360ODS");
- return false;
- }
-
- int finalWidth = Mathf.FloorToInt(_settings.camera.pixelRect.width);
- int finalHeight = Mathf.FloorToInt(_settings.camera.pixelRect.height);
- if (_renderResolution == Resolution.Custom)
- {
- finalWidth = (int)_renderSize.x;
- finalHeight = (int)_renderSize.y;
- }
- else if (_renderResolution != Resolution.Original)
- {
- GetResolution(_renderResolution, ref finalWidth, ref finalHeight);
- }
- _eyeWidth = Mathf.Clamp(finalWidth, 1, 8192);
-
- _eyeHeight = Mathf.Clamp(finalHeight / 2, 1, 4096);
- _eyeHeight -= _eyeHeight & 1;
- finalWidth = _eyeWidth;
- finalHeight = _eyeHeight * 2;
- int aaLevel = GetCameraAntiAliasingLevel(_settings.camera);
-
- _settings.pixelSliceSize = Mathf.Clamp(_settings.pixelSliceSize, 1, _eyeWidth);
- _settings.pixelSliceSize = _settings.pixelSliceSize - (_eyeWidth % _settings.pixelSliceSize);
- _settings.paddingSize = Mathf.Clamp(_settings.paddingSize, 0, 31);
- float offset = _settings.ipd / 2f;
- float aspect = (_settings.pixelSliceSize * 2f) / _eyeHeight;
- if (_cameraGroup == null)
- {
- GameObject go = new GameObject("OdsCameraGroup");
- go.transform.SetParent(this.gameObject.transform);
-
-
- go.hideFlags = this.gameObject.hideFlags;
- _cameraGroup = go.transform;
- }
-
- _leftCameraTop = CreateEye(_leftCameraTop, "LeftEyeTop", 45f, -offset, _eyeHeight / 2, _settings.camera.cullingMask, 90f, aspect, aaLevel);
- _leftCameraBot = CreateEye(_leftCameraBot, "LeftEyeBot", -45f, -offset, _eyeHeight / 2, _settings.camera.cullingMask, 90f, aspect, aaLevel);
- _rightCameraTop = CreateEye(_rightCameraTop, "RightEyeTop", 45f, offset, _eyeHeight / 2, _settings.camera.cullingMask, 90f, aspect, aaLevel);
- _rightCameraBot = CreateEye(_rightCameraBot, "RightEyeBot", -45f, offset, _eyeHeight / 2, _settings.camera.cullingMask, 90f, aspect, aaLevel);
-
- _targetNativePointer = System.IntPtr.Zero;
- if (_final != null)
- {
- _final.DiscardContents();
- if (_final.width != finalWidth || _final.height != finalHeight || _final.antiAliasing != aaLevel)
- {
- RenderTexture.ReleaseTemporary(_final);
- _final = null;
- }
- _final = null;
- }
- if (_final == null)
- {
- _final = RenderTexture.GetTemporary(finalWidth, finalHeight, 0);
- }
-
- _finalMaterial.SetTexture("_leftTopTex", _leftCameraTop.targetTexture);
- _finalMaterial.SetTexture("_leftBotTex", _leftCameraBot.targetTexture);
- _finalMaterial.SetTexture("_rightTopTex", _rightCameraTop.targetTexture);
- _finalMaterial.SetTexture("_rightBotTex", _rightCameraBot.targetTexture);
- _finalMaterial.SetFloat("_pixelSliceSize", _settings.pixelSliceSize);
- _finalMaterial.SetInt("_paddingSize", _settings.paddingSize);
- _finalMaterial.SetFloat("_targetXTexelSize", 1.0f / finalWidth);
- if (_settings.render180Degrees)
- {
- _finalMaterial.DisableKeyword("LAYOUT_EQUIRECT360");
- _finalMaterial.EnableKeyword("LAYOUT_EQUIRECT180");
- }
- else
- {
- _finalMaterial.DisableKeyword("LAYOUT_EQUIRECT180");
- _finalMaterial.EnableKeyword("LAYOUT_EQUIRECT360");
- }
- _Transparency = Transparency.None;
- if ( !NativePlugin.IsBasicEdition() )
- {
- if( (_outputTarget == OutputTarget.VideoFile || _outputTarget == OutputTarget.NamedPipe) && GetEncoderHints().videoHints.transparency != Transparency.None )
- {
- _Transparency = GetEncoderHints().videoHints.transparency;
- }
- else if( _outputTarget == OutputTarget.ImageSequence && GetEncoderHints().imageHints.transparency != Transparency.None )
- {
- _Transparency = GetEncoderHints().imageHints.transparency;
- }
-
- if( _Transparency == Transparency.TopBottom || _Transparency == Transparency.LeftRight )
- {
- InitialiseSideBySideTransparency( finalWidth, finalHeight );
- }
-
- if( _Transparency != Transparency.None )
- {
- _leftCameraTop.backgroundColor = new Color(0f, 0f, 0f, 0f);
- _leftCameraBot.backgroundColor = new Color(0f, 0f, 0f, 0f);
- _rightCameraTop.backgroundColor = new Color(0f, 0f, 0f, 0f);
- _rightCameraBot.backgroundColor = new Color(0f, 0f, 0f, 0f);
- }
- switch ( _Transparency )
- {
- case Transparency.TopBottom: finalHeight *= 2; break;
- case Transparency.LeftRight: finalWidth *= 2; break;
- }
- }
-
- SelectRecordingResolution(finalWidth, finalHeight);
- GenerateFilename();
- if (base.PrepareCapture())
- {
- UpdateInjectionOptions(StereoPacking.TopBottom, _settings.render180Degrees?SphericalVideoLayout.Equirectangular180:SphericalVideoLayout.Equirectangular360);
- return true;
- }
- return false;
- }
- private static void DestroyEye(Camera camera)
- {
- if (camera != null)
- {
- RenderTexture.ReleaseTemporary(camera.targetTexture);
- if (Application.isPlaying)
- {
- GameObject.Destroy(camera.gameObject);
- }
- #if UNITY_EDITOR
- else
- {
- GameObject.DestroyImmediate(camera.gameObject);
- }
- #endif
- }
- }
- public override void OnDestroy()
- {
- _targetNativePointer = System.IntPtr.Zero;
- if (_final != null)
- {
- RenderTexture.ReleaseTemporary(_final);
- _final = null;
- }
- DestroyEye(_leftCameraTop);
- DestroyEye(_leftCameraBot);
- DestroyEye(_rightCameraTop);
- DestroyEye(_rightCameraBot);
- _leftCameraTop = null;
- _leftCameraBot = null;
- _rightCameraTop = null;
- _rightCameraBot = null;
- if (_cameraGroup != null)
- {
- if (Application.isPlaying)
- {
- GameObject.Destroy(_cameraGroup.gameObject);
- }
- #if UNITY_EDITOR
- else
- {
- GameObject.DestroyImmediate(_cameraGroup.gameObject);
- }
- #endif
- _cameraGroup = null;
- }
- if (_finalMaterial)
- {
- Destroy(_finalMaterial);
- _finalMaterial = null;
- }
- base.OnDestroy();
- }
- }
- }
|