void Invalidate() { if (SDKUtils.ContainsFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.STAGE)) { _stage = _stageCandidate; _stageCandidate = null; _invalidate = (INVALIDATION_FLAGS)SDKUtils.SetFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.STAGE, false); } if (SDKUtils.ContainsFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.HMD_CAMERA)) { _HMDCamera = _HMDCameraCandidate; _HMDCameraCandidate = null; _invalidate = (INVALIDATION_FLAGS)SDKUtils.SetFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.HMD_CAMERA, false); } if (SDKUtils.ContainsFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.MR_CAMERA_PREFAB)) { _MRCameraPrefab = _MRCameraPrefabCandidate; _MRCameraPrefabCandidate = null; _invalidate = (INVALIDATION_FLAGS)SDKUtils.SetFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.MR_CAMERA_PREFAB, false); } if (SDKUtils.ContainsFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.EXCLUDE_BEHAVIOURS)) { _excludeBehaviours = _excludeBehavioursCandidate; _excludeBehavioursCandidate = null; _invalidate = (INVALIDATION_FLAGS)SDKUtils.SetFlag((uint)_invalidate, (uint)INVALIDATION_FLAGS.EXCLUDE_BEHAVIOURS, false); } }
public void Dispose() { ReleaseBridgePoseControl(); DestroyAssets(); SDKUtils.DestroyTexture(ref _backgroundRenderTexture); SDKUtils.DestroyTexture(ref _foregroundRenderTexture); SDKUtils.DestroyTexture(ref _complexClipPlaneRenderTexture); }
private void CreateUITexture() { if (SDKUtils.CreateTexture(ref _uiRenderTexture, _resolution.width, _resolution.height, 24, RenderTextureFormat.ARGB32)) { } else { Debug.LogError("LIV: Unable to create UI texture!"); } }
// Renders a single camera in a single texture with occlusion only from opaque objects. // This is the most performant option for mixed reality. // It does not support any transparency in the foreground layer. private void RenderOptimized() { bool debugClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.DEBUG_CLIP_PLANE); bool renderComplexClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.COMPLEX_CLIP_PLANE); bool renderGroundClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.GROUND_CLIP_PLANE); SDKUtils.SetCamera(_cameraInstance, _cameraInstance.transform, _inputFrame, localToWorldMatrix, spectatorLayerMask); _cameraInstance.targetTexture = _optimizedRenderTexture; // Clear alpha channel _writeMaterial.SetInt(SDKShaders.LIV_COLOR_MASK, (int)ColorWriteMask.Alpha); _optimizedRenderingCommandBuffer.Blit(BuiltinRenderTextureType.None, BuiltinRenderTextureType.CurrentActive, _writeMaterial); // Render opaque pixels into alpha channel _writeOpaqueToAlphaMaterial.SetInt(SDKShaders.LIV_COLOR_MASK, (int)ColorWriteMask.Alpha); _optimizedRenderingCommandBuffer.DrawMesh(_clipPlaneMesh, Matrix4x4.identity, _writeOpaqueToAlphaMaterial, 0, 0); // Render clip plane Matrix4x4 clipPlaneTransform = localToWorldMatrix * (Matrix4x4)_inputFrame.clipPlane.transform; _optimizedRenderingCommandBuffer.DrawMesh(_clipPlaneMesh, clipPlaneTransform, GetClipPlaneMaterial(debugClipPlane, renderComplexClipPlane, ColorWriteMask.Alpha), 0, 0); // Render ground clip plane if (renderGroundClipPlane) { Matrix4x4 groundClipPlaneTransform = localToWorldMatrix * (Matrix4x4)_inputFrame.groundClipPlane.transform; _optimizedRenderingCommandBuffer.DrawMesh(_clipPlaneMesh, groundClipPlaneTransform, GetGroundClipPlaneMaterial(debugClipPlane, ColorWriteMask.Alpha), 0, 0); } _cameraInstance.AddCommandBuffer(CameraEvent.AfterEverything, _optimizedRenderingCommandBuffer); // TODO: this is just proprietary SDKShaders.StartRendering(); SDKShaders.StartBackgroundRendering(); InvokePreRenderBackground(); SendTextureToBridge(_optimizedRenderTexture, TEXTURE_ID.OPTIMIZED_COLOR_BUFFER_ID); _cameraInstance.Render(); if (uiRendered) { Graphics.Blit(_uiRenderTexture, _backgroundRenderTexture, _uiTransparentMaterial); } InvokePostRenderBackground(); _cameraInstance.targetTexture = null; SDKShaders.StopBackgroundRendering(); SDKShaders.StopRendering(); _cameraInstance.RemoveCommandBuffer(CameraEvent.AfterEverything, _optimizedRenderingCommandBuffer); _optimizedRenderingCommandBuffer.Clear(); }
private void CreateOptimizedTexture() { if (SDKUtils.CreateTexture(ref _optimizedRenderTexture, _resolution.width, _resolution.height, 24, RenderTextureFormat.ARGB32)) { #if UNITY_EDITOR _optimizedRenderTexture.name = "LIV.OptimizedRenderTexture"; #endif } else { Debug.LogError("LIV: Unable to create optimized texture!"); } }
private void CreateComplexClipPlaneTexture() { if (SDKUtils.CreateTexture(ref _complexClipPlaneRenderTexture, _inputFrame.clipPlane.width, _inputFrame.clipPlane.height, 0, RenderTextureFormat.ARGB32)) { #if UNITY_EDITOR _complexClipPlaneRenderTexture.name = "LIV.ComplexClipPlaneRenderTexture"; #endif } else { Debug.LogError("LIV: Unable to create complex clip plane texture!"); } }
private void UpdateTextures() { if (SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.BACKGROUND_RENDER)) { if ( _backgroundRenderTexture == null || _backgroundRenderTexture.width != _resolution.width || _backgroundRenderTexture.height != _resolution.height ) { CreateBackgroundTexture(); } } else { SDKUtils.DestroyTexture(ref _backgroundRenderTexture); } if (SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.FOREGROUND_RENDER)) { if ( _foregroundRenderTexture == null || _foregroundRenderTexture.width != _resolution.width || _foregroundRenderTexture.height != _resolution.height ) { CreateForegroundTexture(); } } else { SDKUtils.DestroyTexture(ref _foregroundRenderTexture); } if (SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.COMPLEX_CLIP_PLANE)) { if ( _complexClipPlaneRenderTexture == null || _complexClipPlaneRenderTexture.width != _inputFrame.clipPlane.width || _complexClipPlaneRenderTexture.height != _inputFrame.clipPlane.height ) { CreateComplexClipPlaneTexture(); } } else { SDKUtils.DestroyTexture(ref _complexClipPlaneRenderTexture); } }
void SendTextureToBridge(RenderTexture texture, TEXTURE_ID id) { SDKBridge.AddTexture(new SDKTexture() { id = id, texturePtr = texture.GetNativeTexturePtr(), SharedHandle = System.IntPtr.Zero, device = SDKUtils.GetDevice(), dummy = 0, type = TEXTURE_TYPE.COLOR_BUFFER, format = TEXTURE_FORMAT.ARGB32, colorSpace = SDKUtils.GetColorSpace(texture), width = texture.width, height = texture.height }); }
// Default render without any special changes private void RenderBackground() { SDKUtils.SetCamera(_cameraInstance, _cameraInstance.transform, _inputFrame, localToWorldMatrix, spectatorLayerMask); _cameraInstance.targetTexture = _backgroundRenderTexture; RenderTexture tempRenderTexture = null; bool overridePostProcessing = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.OVERRIDE_POST_PROCESSING); if (overridePostProcessing) { tempRenderTexture = RenderTexture.GetTemporary(_backgroundRenderTexture.width, _backgroundRenderTexture.height, 0, _backgroundRenderTexture.format); _captureTextureCommandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, tempRenderTexture); _applyTextureCommandBuffer.Blit(tempRenderTexture, BuiltinRenderTextureType.CurrentActive); _cameraInstance.AddCommandBuffer(_captureTextureEvent, _captureTextureCommandBuffer); _cameraInstance.AddCommandBuffer(_applyTextureEvent, _applyTextureCommandBuffer); } SDKShaders.StartRendering(); SDKShaders.StartBackgroundRendering(); InvokePreRenderBackground(); SendTextureToBridge(_backgroundRenderTexture, TEXTURE_ID.BACKGROUND_COLOR_BUFFER_ID); _cameraInstance.Render(); if (uiRendered) { Graphics.Blit(_uiRenderTexture, _backgroundRenderTexture, _uiTransparentMaterial); } InvokePostRenderBackground(); _cameraInstance.targetTexture = null; SDKShaders.StopBackgroundRendering(); SDKShaders.StopRendering(); if (overridePostProcessing) { _cameraInstance.RemoveCommandBuffer(_captureTextureEvent, _captureTextureCommandBuffer); _cameraInstance.RemoveCommandBuffer(_applyTextureEvent, _applyTextureCommandBuffer); _captureTextureCommandBuffer.Clear(); _applyTextureCommandBuffer.Clear(); RenderTexture.ReleaseTemporary(tempRenderTexture); } }
public static void CreateBridgeOutputFrame(SDKRender render) { RENDERING_PIPELINE renderingPipeline = RENDERING_PIPELINE.UNDEFINED; #if LIV_UNIVERSAL_RENDER renderingPipeline = RENDERING_PIPELINE.UNIVERSAL; #else if (render.cameraInstance != null) { renderingPipeline = SDKUtils.GetRenderingPipeline(render.cameraInstance.actualRenderingPath); } #endif SDKBridge.CreateFrame(new SDKOutputFrame() { renderingPipeline = renderingPipeline, trackedSpace = SDKUtils.GetTrackedSpace(render.stageTransform == null ? render.stage : render.stageTransform) }); }
// Default render without any special changes private void RenderBackground() { SDKUtils.SetCamera(_cameraInstance, _cameraInstance.transform, _inputFrame, localToWorldMatrix, spectatorLayerMask); _cameraInstance.targetTexture = _backgroundRenderTexture; RenderTexture tempRenderTexture = null; bool overridePostProcessing = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.OVERRIDE_POST_PROCESSING); if (overridePostProcessing) { tempRenderTexture = RenderTexture.GetTemporary(_backgroundRenderTexture.width, _backgroundRenderTexture.height, 0, _backgroundRenderTexture.format); #if UNITY_EDITOR tempRenderTexture.name = "LIV.TemporaryRenderTexture"; #endif _captureTexturePass.commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, tempRenderTexture); _applyTexturePass.commandBuffer.Blit(tempRenderTexture, BuiltinRenderTextureType.CurrentActive); SDKUniversalRenderFeature.AddPass(_captureTexturePass); SDKUniversalRenderFeature.AddPass(_applyTexturePass); } SDKShaders.StartRendering(); SDKShaders.StartBackgroundRendering(); InvokePreRenderBackground(); SendTextureToBridge(_backgroundRenderTexture, TEXTURE_ID.BACKGROUND_COLOR_BUFFER_ID); _cameraInstance.Render(); InvokePostRenderBackground(); _cameraInstance.targetTexture = null; SDKShaders.StopBackgroundRendering(); SDKShaders.StopRendering(); if (overridePostProcessing) { _captureTexturePass.commandBuffer.Clear(); _applyTexturePass.commandBuffer.Clear(); RenderTexture.ReleaseTemporary(tempRenderTexture); } SDKUniversalRenderFeature.ClearPasses(); }
public void Render() { UpdateBridgeResolution(); UpdateBridgeInputFrame(); SDKUtils.ApplyUserSpaceTransform(this); UpdateTextures(); InvokePreRender(); if (canRenderBackground) { RenderBackground(); } if (canRenderForeground) { RenderForeground(); } if (canRenderOptimized) { RenderOptimized(); } IvokePostRender(); SDKUtils.CreateBridgeOutputFrame(this); SDKBridge.IssuePluginEvent(); }
/// <summary> /// Control camera pose by calling this method each frame. The pose is released when you stop calling it. /// </summary> /// <remarks> /// <para>By default the pose is set in worldspace, turn on local space for using the stage relative space instead.</para> /// </remarks> /// <example> /// <code> /// public class ControlCameraPose : MonoBehaviour /// { /// [SerializeField] LIV.SDK.Unity.LIV _liv; /// [SerializeField] float _fov = 60f; /// /// private void Update() /// { /// if(_liv.isActive) /// { /// _liv.render.SetPose(transform.position, transform.rotation, _fov); /// } /// } /// } /// </code> /// </example> public bool SetPose(Vector3 position, Quaternion rotation, float verticalFieldOfView = 60f, bool useLocalSpace = false) { if (_inputFrame.frameid == 0) { return(false); } SDKPose inputPose = _inputFrame.pose; float aspect = 1f; if (_resolution.height > 0) { aspect = (float)_resolution.width / (float)_resolution.height; } if (!useLocalSpace) { Matrix4x4 worldToLocal = Matrix4x4.identity; Transform localTransform = stageTransform == null ? stage : stageTransform; if (localTransform != null) { worldToLocal = localTransform.worldToLocalMatrix; } position = worldToLocal.MultiplyPoint(position); rotation = SDKUtils.RotateQuaternionByMatrix(worldToLocal, rotation); } _requestedPose = new SDKPose() { localPosition = position, localRotation = rotation, verticalFieldOfView = verticalFieldOfView, projectionMatrix = Matrix4x4.Perspective(verticalFieldOfView, aspect, inputPose.nearClipPlane, inputPose.farClipPlane) }; _requestedPoseFrameIndex = Time.frameCount; return(_inputFrame.priority.pose <= (sbyte)PRIORITY.GAME); }
private void DestroyAssets() { if (_cameraInstance != null) { Object.Destroy(_cameraInstance.gameObject); _cameraInstance = null; } SDKUtils.DestroyObject <Mesh>(ref _clipPlaneMesh); SDKUtils.DestroyObject <Material>(ref _clipPlaneSimpleMaterial); SDKUtils.DestroyObject <Material>(ref _clipPlaneSimpleDebugMaterial); SDKUtils.DestroyObject <Material>(ref _clipPlaneComplexMaterial); SDKUtils.DestroyObject <Material>(ref _clipPlaneComplexDebugMaterial); SDKUtils.DestroyObject <Material>(ref _writeOpaqueToAlphaMaterial); SDKUtils.DestroyObject <Material>(ref _combineAlphaMaterial); SDKUtils.DestroyObject <Material>(ref _writeMaterial); SDKUtils.DestroyObject <Material>(ref _forceForwardRenderingMaterial); SDKUtils.DisposeObject <CommandBuffer>(ref _clipPlaneCommandBuffer); SDKUtils.DisposeObject <CommandBuffer>(ref _combineAlphaCommandBuffer); SDKUtils.DisposeObject <CommandBuffer>(ref _captureTextureCommandBuffer); SDKUtils.DisposeObject <CommandBuffer>(ref _applyTextureCommandBuffer); SDKUtils.DisposeObject <CommandBuffer>(ref _optimizedRenderingCommandBuffer); }
// Renders a single camera in a single texture with occlusion only from opaque objects. // This is the most performant option for mixed reality. // It does not support any transparency in the foreground layer. private void RenderOptimized() { if (!SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.BACKGROUND_RENDER) || _backgroundRenderTexture == null || _foregroundRenderTexture == null) { return; } bool debugClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.DEBUG_CLIP_PLANE); bool renderComplexClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.COMPLEX_CLIP_PLANE); bool renderGroundClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.GROUND_CLIP_PLANE); MonoBehaviour[] behaviours = null; bool[] wasBehaviourEnabled = null; if (disableStandardAssets) { SDKUtils.DisableStandardAssets(_cameraInstance, ref behaviours, ref wasBehaviourEnabled); } SDKUtils.SetCamera(_cameraInstance, _cameraInstance.transform, _inputFrame, localToWorldMatrix, spectatorLayerMask); _cameraInstance.targetTexture = _foregroundRenderTexture; // Clear alpha channel _writeMaterial.SetInt(SDKShaders.LIV_COLOR_MASK, (int)ColorWriteMask.Alpha); _optimizedRenderingCommandBuffer.Blit(BuiltinRenderTextureType.None, BuiltinRenderTextureType.CurrentActive, _writeMaterial); // Render opaque pixels into alpha channel _writeOpaqueToAlphaMaterial.SetInt(SDKShaders.LIV_COLOR_MASK, (int)ColorWriteMask.Alpha); _optimizedRenderingCommandBuffer.DrawMesh(_clipPlaneMesh, Matrix4x4.identity, _writeOpaqueToAlphaMaterial, 0, 0); // Render clip plane Matrix4x4 clipPlaneTransform = localToWorldMatrix * (Matrix4x4)_inputFrame.clipPlane.transform; _optimizedRenderingCommandBuffer.DrawMesh(_clipPlaneMesh, clipPlaneTransform, GetClipPlaneMaterial(debugClipPlane, renderComplexClipPlane, ColorWriteMask.Alpha), 0, 0); // Render ground clip plane if (renderGroundClipPlane) { Matrix4x4 groundClipPlaneTransform = localToWorldMatrix * (Matrix4x4)_inputFrame.groundClipPlane.transform; _optimizedRenderingCommandBuffer.DrawMesh(_clipPlaneMesh, groundClipPlaneTransform, GetGroundClipPlaneMaterial(debugClipPlane, ColorWriteMask.Alpha), 0, 0); } // Copy content to background texture _optimizedRenderingCommandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, _backgroundRenderTexture); _cameraInstance.AddCommandBuffer(CameraEvent.AfterEverything, _optimizedRenderingCommandBuffer); if (useDeferredRendering) { SDKUtils.ForceForwardRendering(cameraInstance, _clipPlaneMesh, _forceForwardRenderingMaterial); } // TODO: this is just proprietary SDKShaders.StartRendering(); SDKShaders.StartBackgroundRendering(); InvokePreRenderBackground(); SendTextureToBridge(_backgroundRenderTexture, TEXTURE_ID.BACKGROUND_COLOR_BUFFER_ID); SendTextureToBridge(_foregroundRenderTexture, TEXTURE_ID.FOREGROUND_COLOR_BUFFER_ID); _cameraInstance.Render(); InvokePostRenderBackground(); _cameraInstance.targetTexture = null; SDKShaders.StopBackgroundRendering(); SDKShaders.StopRendering(); _cameraInstance.RemoveCommandBuffer(CameraEvent.AfterEverything, _optimizedRenderingCommandBuffer); _optimizedRenderingCommandBuffer.Clear(); SDKUtils.RestoreStandardAssets(ref behaviours, ref wasBehaviourEnabled); }
private void CreateAssets() { bool cameraReferenceEnabled = cameraReference.enabled; if (cameraReferenceEnabled) { cameraReference.enabled = false; } bool cameraReferenceActive = cameraReference.gameObject.activeSelf; if (cameraReferenceActive) { cameraReference.gameObject.SetActive(false); } GameObject cloneGO = (GameObject)Object.Instantiate(cameraReference.gameObject, _liv.stage); _cameraInstance = (Camera)cloneGO.GetComponent("Camera"); SDKUtils.CleanCameraBehaviours(_cameraInstance, _liv.excludeBehaviours); if (cameraReferenceActive != cameraReference.gameObject.activeSelf) { cameraReference.gameObject.SetActive(cameraReferenceActive); } if (cameraReferenceEnabled != cameraReference.enabled) { cameraReference.enabled = cameraReferenceEnabled; } _cameraInstance.name = "LIV Camera"; if (_cameraInstance.tag == "MainCamera") { _cameraInstance.tag = "Untagged"; } _cameraInstance.transform.localScale = Vector3.one; _cameraInstance.rect = new Rect(0, 0, 1, 1); _cameraInstance.depth = 0; _cameraInstance.stereoTargetEye = StereoTargetEyeMask.None; _cameraInstance.allowMSAA = false; _cameraInstance.enabled = false; _cameraInstance.gameObject.SetActive(true); _cameraInstance.GetComponent <RoR2.SceneCamera>().cameraRigController = cameraReference.GetComponent <RoR2.SceneCamera>().cameraRigController; _cameraPostProcess = _cameraInstance.GetComponent <PostProcessLayer>(); _clipPlaneMesh = new Mesh(); SDKUtils.CreateClipPlane(_clipPlaneMesh, 10, 10, true, 1000f); _clipPlaneSimpleMaterial = new Material(SDKShaders.clipPlaneSimpleMaterial); _clipPlaneSimpleDebugMaterial = new Material(SDKShaders.clipPlaneSimpleDebugMaterial); _clipPlaneComplexMaterial = new Material(SDKShaders.clipPlaneComplexMaterial); _clipPlaneComplexDebugMaterial = new Material(SDKShaders.clipPlaneComplexDebugMaterial); _writeOpaqueToAlphaMaterial = new Material(SDKShaders.writeOpaqueToAlphaMaterial); _combineAlphaMaterial = new Material(SDKShaders.combineAlphaMaterial); _writeMaterial = new Material(SDKShaders.writeMaterial); _forceForwardRenderingMaterial = new Material(SDKShaders.forceForwardRenderingMaterial); _uiTransparentMaterial = VRMod.VRMod.VRAssetBundle.LoadAsset <Material>("UnlitTransparentMat"); _clipPlaneCommandBuffer = new CommandBuffer(); _combineAlphaCommandBuffer = new CommandBuffer(); _captureTextureCommandBuffer = new CommandBuffer(); _applyTextureCommandBuffer = new CommandBuffer(); _optimizedRenderingCommandBuffer = new CommandBuffer(); GameObject uiCamObject = new GameObject("LIV UI Camera"); uiCamObject.transform.SetParent(_cameraInstance.transform); uiCamObject.transform.localPosition = Vector3.zero; uiCamObject.transform.localRotation = Quaternion.identity; uiCamObject.transform.localScale = Vector3.one; _uiCameraInstance = uiCamObject.AddComponent <Camera>(); _uiCameraInstance.cullingMask = (1 << RoR2.LayerIndex.triggerZone.intVal); _uiCameraInstance.clearFlags = CameraClearFlags.SolidColor; _uiCameraInstance.backgroundColor = new Color(0, 0, 0, 0); _uiCameraInstance.rect = new Rect(0, 0, 1, 1); _uiCameraInstance.depth = 1; _uiCameraInstance.stereoTargetEye = StereoTargetEyeMask.None; _uiCameraInstance.allowHDR = false; _uiCameraInstance.allowMSAA = false; _uiCameraInstance.enabled = false; _uiCameraInstance.gameObject.SetActive(true); }
public static bool FeatureEnabled(FEATURES features, FEATURES feature) { return(SDKUtils.ContainsFlag((ulong)features, (ulong)feature)); }
private void CreateAssets() { bool cameraReferenceEnabled = cameraReference.enabled; if (cameraReferenceEnabled) { cameraReference.enabled = false; } bool cameraReferenceActive = cameraReference.gameObject.activeSelf; if (cameraReferenceActive) { cameraReference.gameObject.SetActive(false); } GameObject cloneGO = (GameObject)Object.Instantiate(cameraReference.gameObject, _liv.stage); _cameraInstance = (Camera)cloneGO.GetComponent("Camera"); SDKUtils.CleanCameraBehaviours(_cameraInstance, _liv.excludeBehaviours); if (cameraReferenceActive != cameraReference.gameObject.activeSelf) { cameraReference.gameObject.SetActive(cameraReferenceActive); } if (cameraReferenceEnabled != cameraReference.enabled) { cameraReference.enabled = cameraReferenceEnabled; } _cameraInstance.name = "LIV Camera"; if (_cameraInstance.tag == "MainCamera") { _cameraInstance.tag = "Untagged"; } _cameraInstance.transform.localScale = Vector3.one; _cameraInstance.rect = new Rect(0, 0, 1, 1); _cameraInstance.depth = 0; #if UNITY_5_4_OR_NEWER _cameraInstance.stereoTargetEye = StereoTargetEyeMask.None; #endif #if UNITY_5_6_OR_NEWER _cameraInstance.allowMSAA = false; #endif _cameraInstance.enabled = false; _cameraInstance.gameObject.SetActive(true); _clipPlaneMesh = new Mesh(); SDKUtils.CreateClipPlane(_clipPlaneMesh, 10, 10, true, 1000f); _clipPlaneSimpleMaterial = new Material(Shader.Find(SDKShaders.LIV_CLIP_PLANE_SIMPLE_SHADER)); _clipPlaneSimpleDebugMaterial = new Material(Shader.Find(SDKShaders.LIV_CLIP_PLANE_SIMPLE_DEBUG_SHADER)); _clipPlaneComplexMaterial = new Material(Shader.Find(SDKShaders.LIV_CLIP_PLANE_COMPLEX_SHADER)); _clipPlaneComplexDebugMaterial = new Material(Shader.Find(SDKShaders.LIV_CLIP_PLANE_COMPLEX_DEBUG_SHADER)); _writeOpaqueToAlphaMaterial = new Material(Shader.Find(SDKShaders.LIV_WRITE_OPAQUE_TO_ALPHA_SHADER)); _combineAlphaMaterial = new Material(Shader.Find(SDKShaders.LIV_COMBINE_ALPHA_SHADER)); _writeMaterial = new Material(Shader.Find(SDKShaders.LIV_WRITE_SHADER)); _forceForwardRenderingMaterial = new Material(Shader.Find(SDKShaders.LIV_FORCE_FORWARD_RENDERING_SHADER)); _clipPlaneCommandBuffer = new CommandBuffer(); _combineAlphaCommandBuffer = new CommandBuffer(); _captureTextureCommandBuffer = new CommandBuffer(); _applyTextureCommandBuffer = new CommandBuffer(); _optimizedRenderingCommandBuffer = new CommandBuffer(); #if UNITY_EDITOR _clipPlaneMesh.name = "LIV.clipPlane"; _clipPlaneSimpleMaterial.name = "LIV.clipPlaneSimple"; _clipPlaneSimpleDebugMaterial.name = "LIV.clipPlaneSimpleDebug"; _clipPlaneComplexMaterial.name = "LIV.clipPlaneComplex"; _clipPlaneComplexDebugMaterial.name = "LIV.clipPlaneComplexDebug"; _writeOpaqueToAlphaMaterial.name = "LIV.writeOpaqueToAlpha"; _combineAlphaMaterial.name = "LIV.combineAlpha"; _writeMaterial.name = "LIV.write"; _forceForwardRenderingMaterial.name = "LIV.forceForwardRendering"; _clipPlaneCommandBuffer.name = "LIV.renderClipPlanes"; _combineAlphaCommandBuffer.name = "LIV.foregroundCombineAlpha"; _captureTextureCommandBuffer.name = "LIV.captureTexture"; _applyTextureCommandBuffer.name = "LIV.applyTexture"; _optimizedRenderingCommandBuffer.name = "LIV.optimizedRendering"; #endif }
// Extract the image which is in front of our clip plane // The compositing is heavily relying on the alpha channel, therefore we want to make sure it does // not get corrupted by the postprocessing or any shader private void RenderForeground() { bool debugClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.DEBUG_CLIP_PLANE); bool renderComplexClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.COMPLEX_CLIP_PLANE); bool renderGroundClipPlane = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.GROUND_CLIP_PLANE); bool overridePostProcessing = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.OVERRIDE_POST_PROCESSING); bool fixPostEffectsAlpha = SDKUtils.FeatureEnabled(inputFrame.features, FEATURES.FIX_FOREGROUND_ALPHA) | _liv.fixPostEffectsAlpha; MonoBehaviour[] behaviours = null; bool[] wasBehaviourEnabled = null; if (disableStandardAssets) { SDKUtils.DisableStandardAssets(_cameraInstance, ref behaviours, ref wasBehaviourEnabled); } // Capture camera defaults CameraClearFlags capturedClearFlags = _cameraInstance.clearFlags; Color capturedBgColor = _cameraInstance.backgroundColor; Color capturedFogColor = RenderSettings.fogColor; // Make sure that fog does not corrupt alpha channel RenderSettings.fogColor = new Color(capturedFogColor.r, capturedFogColor.g, capturedFogColor.b, 0f); SDKUtils.SetCamera(_cameraInstance, _cameraInstance.transform, _inputFrame, localToWorldMatrix, spectatorLayerMask); _cameraInstance.clearFlags = CameraClearFlags.Color; _cameraInstance.backgroundColor = Color.clear; _cameraInstance.targetTexture = _foregroundRenderTexture; RenderTexture capturedAlphaRenderTexture = RenderTexture.GetTemporary(_foregroundRenderTexture.width, _foregroundRenderTexture.height, 0, _foregroundRenderTexture.format); #if UNITY_EDITOR capturedAlphaRenderTexture.name = "LIV.CapturedAlphaRenderTexture"; #endif // Render opaque pixels into alpha channel _clipPlaneCommandBuffer.DrawMesh(_clipPlaneMesh, Matrix4x4.identity, _writeOpaqueToAlphaMaterial, 0, 0); // Render clip plane Matrix4x4 clipPlaneTransform = localToWorldMatrix * (Matrix4x4)_inputFrame.clipPlane.transform; _clipPlaneCommandBuffer.DrawMesh(_clipPlaneMesh, clipPlaneTransform, GetClipPlaneMaterial(debugClipPlane, renderComplexClipPlane, ColorWriteMask.All), 0, 0); // Render ground clip plane if (renderGroundClipPlane) { Matrix4x4 groundClipPlaneTransform = localToWorldMatrix * (Matrix4x4)_inputFrame.groundClipPlane.transform; _clipPlaneCommandBuffer.DrawMesh(_clipPlaneMesh, groundClipPlaneTransform, GetGroundClipPlaneMaterial(debugClipPlane, ColorWriteMask.All), 0, 0); } // Copy alpha in to texture _clipPlaneCommandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, capturedAlphaRenderTexture); _cameraInstance.AddCommandBuffer(_clipPlaneCameraEvent, _clipPlaneCommandBuffer); // Fix alpha corruption by post processing RenderTexture tempRenderTexture = null; if (overridePostProcessing || fixPostEffectsAlpha) { tempRenderTexture = RenderTexture.GetTemporary(_foregroundRenderTexture.width, _foregroundRenderTexture.height, 0, _foregroundRenderTexture.format); #if UNITY_EDITOR tempRenderTexture.name = "LIV.TemporaryRenderTexture"; #endif _captureTextureCommandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, tempRenderTexture); _cameraInstance.AddCommandBuffer(_captureTextureEvent, _captureTextureCommandBuffer); _writeMaterial.SetInt(SDKShaders.LIV_COLOR_MASK, overridePostProcessing ? (int)ColorWriteMask.All : (int)ColorWriteMask.Alpha); _applyTextureCommandBuffer.Blit(tempRenderTexture, BuiltinRenderTextureType.CurrentActive, _writeMaterial); _cameraInstance.AddCommandBuffer(_applyTextureEvent, _applyTextureCommandBuffer); } // Combine captured alpha with result alpha _combineAlphaMaterial.SetInt(SDKShaders.LIV_COLOR_MASK, (int)ColorWriteMask.Alpha); _combineAlphaCommandBuffer.Blit(capturedAlphaRenderTexture, BuiltinRenderTextureType.CurrentActive, _combineAlphaMaterial); _cameraInstance.AddCommandBuffer(_clipPlaneCombineAlphaCameraEvent, _combineAlphaCommandBuffer); if (useDeferredRendering) { SDKUtils.ForceForwardRendering(cameraInstance, _clipPlaneMesh, _forceForwardRenderingMaterial); } SDKShaders.StartRendering(); SDKShaders.StartForegroundRendering(); InvokePreRenderForeground(); SendTextureToBridge(_foregroundRenderTexture, TEXTURE_ID.FOREGROUND_COLOR_BUFFER_ID); _cameraInstance.Render(); InvokePostRenderForeground(); _cameraInstance.targetTexture = null; SDKShaders.StopForegroundRendering(); SDKShaders.StopRendering(); if (overridePostProcessing || fixPostEffectsAlpha) { _cameraInstance.RemoveCommandBuffer(_captureTextureEvent, _captureTextureCommandBuffer); _cameraInstance.RemoveCommandBuffer(_applyTextureEvent, _applyTextureCommandBuffer); _captureTextureCommandBuffer.Clear(); _applyTextureCommandBuffer.Clear(); RenderTexture.ReleaseTemporary(tempRenderTexture); } _cameraInstance.RemoveCommandBuffer(_clipPlaneCameraEvent, _clipPlaneCommandBuffer); _cameraInstance.RemoveCommandBuffer(_clipPlaneCombineAlphaCameraEvent, _combineAlphaCommandBuffer); RenderTexture.ReleaseTemporary(capturedAlphaRenderTexture); _clipPlaneCommandBuffer.Clear(); _combineAlphaCommandBuffer.Clear(); // Revert camera defaults _cameraInstance.clearFlags = capturedClearFlags; _cameraInstance.backgroundColor = capturedBgColor; RenderSettings.fogColor = capturedFogColor; SDKUtils.RestoreStandardAssets(ref behaviours, ref wasBehaviourEnabled); }