diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Controllers/CameraController.cs b/Assets/Scripts/Streamingle/StreamingleControl/Controllers/CameraController.cs
index 63935b1d..705f3949 100644
--- a/Assets/Scripts/Streamingle/StreamingleControl/Controllers/CameraController.cs
+++ b/Assets/Scripts/Streamingle/StreamingleControl/Controllers/CameraController.cs
@@ -280,8 +280,7 @@ public class CameraManager : MonoBehaviour, IController
[SerializeField] private bool useRealtimeBlend = true;
// 블렌드용 렌더 텍스처와 카메라
- private RenderTexture blendRenderTexture;
- private RenderTexture prevCameraRenderTexture; // 실시간 블렌딩용 이전 카메라 렌더 텍스처
+ private RenderTexture prevCameraRenderTexture; // 블렌딩용 이전 카메라 렌더 텍스처
private Camera blendCamera;
private CinemachineCamera currentCamera;
@@ -350,13 +349,11 @@ public class CameraManager : MonoBehaviour, IController
}
// 블렌드 리소스 정리
- CameraBlendController.Reset();
-
- if (blendRenderTexture != null)
+ if (prevCameraRenderTexture != null)
{
- blendRenderTexture.Release();
- Destroy(blendRenderTexture);
- blendRenderTexture = null;
+ prevCameraRenderTexture.Release();
+ Destroy(prevCameraRenderTexture);
+ prevCameraRenderTexture = null;
}
if (blendCamera != null)
@@ -785,7 +782,12 @@ public class CameraManager : MonoBehaviour, IController
if (blendCoroutine != null)
{
StopCoroutine(blendCoroutine);
- CameraBlendController.EndBlend();
+ // UI 오버레이 숨기기
+ var overlay = CameraBlendOverlay.Instance;
+ if (overlay != null)
+ {
+ overlay.Hide();
+ }
}
blendCoroutine = StartCoroutine(BlendTransitionCoroutine(index, customBlendTime ?? blendTime));
@@ -923,38 +925,6 @@ public class CameraManager : MonoBehaviour, IController
}
- ///
- /// 블렌드용 렌더 텍스처 생성/갱신
- ///
- private void EnsureBlendRenderTexture()
- {
- int width = Screen.width;
- int height = Screen.height;
-
- // 이미 적절한 크기의 텍스처가 있으면 재사용
- if (blendRenderTexture != null &&
- blendRenderTexture.width == width &&
- blendRenderTexture.height == height)
- {
- return;
- }
-
- // 기존 텍스처 해제
- if (blendRenderTexture != null)
- {
- blendRenderTexture.Release();
- Destroy(blendRenderTexture);
- }
-
- // 새 렌더 텍스처 생성 - 색상 전용 (depth 없음), 리니어 색공간에서 올바른 블렌딩
- var descriptor = new RenderTextureDescriptor(width, height, RenderTextureFormat.ARGB32, 0); // depth = 0
- descriptor.sRGB = true; // sRGB 텍스처로 설정하여 리니어 파이프라인과 일치
- blendRenderTexture = new RenderTexture(descriptor);
- blendRenderTexture.name = "CameraBlendRT";
- blendRenderTexture.Create();
-
- }
-
///
/// 크로스 디졸브 블렌드 전환 코루틴
///
@@ -971,16 +941,15 @@ public class CameraManager : MonoBehaviour, IController
}
///
- /// 스냅샷 블렌딩 (이전 화면 정지)
+ /// 스냅샷 블렌딩 (이전 화면 정지) - UI 오버레이 방식
///
private IEnumerator SnapshotBlendTransitionCoroutine(int targetIndex, float duration)
{
isBlending = true;
- // 블렌드 텍스처 준비
- EnsureBlendRenderTexture();
-
- if (blendRenderTexture == null)
+ // 메인 카메라의 현재 위치/회전/FOV를 저장
+ Camera mainCamera = Camera.main;
+ if (mainCamera == null)
{
SetImmediate(targetIndex);
isBlending = false;
@@ -988,80 +957,14 @@ public class CameraManager : MonoBehaviour, IController
yield break;
}
- // 렌더 패스에서 현재 프레임(포스트 프로세싱 적용 후)을 캡처하도록 요청
- CameraBlendController.RequestCapture(blendRenderTexture);
-
- // 캡처가 완료될 때까지 대기 (다음 프레임 렌더링 후)
- yield return new WaitForEndOfFrame();
- yield return null; // 렌더 패스가 실행될 때까지 한 프레임 더 대기
-
- // 캡처 완료 확인
- if (!CameraBlendController.CaptureReady)
- {
- CameraBlendController.EndBlend();
- SetImmediate(targetIndex);
- isBlending = false;
- blendCoroutine = null;
- yield break;
- }
-
- // 블렌딩 시작 - BlendAmount = 1 (이전 카메라만 보임)
- CameraBlendController.StartBlendAfterCapture();
- CameraBlendController.BlendAmount = 1f;
-
- // 카메라 전환 (이제 BlendAmount=1이므로 캡처된 이전 화면만 보임)
- SetImmediate(targetIndex);
-
- // 블렌드 진행: 1 → 0 (이전 카메라가 서서히 사라지고 새 카메라가 드러남)
- float elapsed = 0f;
- while (elapsed < duration)
- {
- elapsed += Time.deltaTime;
- float t = Mathf.Clamp01(elapsed / duration);
- // 부드러운 이징 적용 (SmoothStep)
- t = t * t * (3f - 2f * t);
- // 1에서 0으로: 이전 카메라가 서서히 사라짐
- CameraBlendController.BlendAmount = 1f - t;
- yield return null;
- }
-
- CameraBlendController.BlendAmount = 0f;
-
- // 블렌딩 종료
- CameraBlendController.EndBlend();
-
- isBlending = false;
- blendCoroutine = null;
- }
-
- ///
- /// 실시간 블렌딩 (두 카메라 동시 렌더링)
- /// 이전 카메라 위치를 저장해두고 그 위치에서 렌더링, 서서히 사라지면서 새 카메라가 드러남
- ///
- private IEnumerator RealtimeBlendTransitionCoroutine(int targetIndex, float duration)
- {
- isBlending = true;
-
- // 이전 카메라 프리셋 저장
- var prevPreset = currentPreset;
- if (prevPreset == null || prevPreset.virtualCamera == null)
- {
- SetImmediate(targetIndex);
- isBlending = false;
- blendCoroutine = null;
- yield break;
- }
-
- // SetImmediate 호출 전에 이전 카메라의 위치/회전/FOV를 저장
- Vector3 prevCameraPosition = prevPreset.virtualCamera.transform.position;
- Quaternion prevCameraRotation = prevPreset.virtualCamera.transform.rotation;
- float prevCameraFOV = prevPreset.virtualCamera.Lens.FieldOfView;
+ Vector3 prevCameraPosition = mainCamera.transform.position;
+ Quaternion prevCameraRotation = mainCamera.transform.rotation;
+ float prevCameraFOV = mainCamera.fieldOfView;
// 블렌드 텍스처 준비
- EnsureBlendRenderTexture();
EnsurePrevCameraRenderTexture();
- if (blendRenderTexture == null || prevCameraRenderTexture == null)
+ if (prevCameraRenderTexture == null)
{
SetImmediate(targetIndex);
isBlending = false;
@@ -1079,34 +982,122 @@ public class CameraManager : MonoBehaviour, IController
yield break;
}
+ // UI 오버레이 준비
+ var overlay = CameraBlendOverlay.GetOrCreate();
+
+ // 블렌드 카메라를 현재 메인 카메라 위치로 설정하고 렌더링 (스냅샷 캡처)
+ blendCamera.transform.SetPositionAndRotation(prevCameraPosition, prevCameraRotation);
+ blendCamera.fieldOfView = prevCameraFOV;
+ blendCamera.targetTexture = prevCameraRenderTexture;
+ blendCamera.Render();
+
+ // UI 오버레이 표시 (알파 1 = 완전 불투명)
+ overlay.Show(prevCameraRenderTexture);
+ overlay.SetAlpha(1f);
+
+ // 새 카메라로 전환
+ SetImmediate(targetIndex);
+
+ // 블렌드 진행: 알파 1 → 0 (스냅샷이 서서히 사라지고 새 카메라가 드러남)
+ float elapsed = 0f;
+ while (elapsed < duration)
+ {
+ // 다음 프레임까지 대기
+ yield return null;
+
+ elapsed += Time.deltaTime;
+ float t = Mathf.Clamp01(elapsed / duration);
+ // 부드러운 이징 적용 (SmoothStep)
+ t = t * t * (3f - 2f * t);
+ // 알파를 1에서 0으로: 스냅샷이 서서히 사라짐
+ overlay.SetAlpha(1f - t);
+ }
+
+ // 블렌딩 종료
+ overlay.Hide();
+
+ isBlending = false;
+ blendCoroutine = null;
+ }
+
+ ///
+ /// 실시간 블렌딩 (UI 오버레이 방식)
+ /// 이전 카메라 위치를 저장해두고 그 위치에서 렌더링, UI로 표시하고 서서히 사라지게 함
+ ///
+ private IEnumerator RealtimeBlendTransitionCoroutine(int targetIndex, float duration)
+ {
+ isBlending = true;
+
+ // 이전 카메라 프리셋 저장
+ var prevPreset = currentPreset;
+ if (prevPreset == null || prevPreset.virtualCamera == null)
+ {
+ SetImmediate(targetIndex);
+ isBlending = false;
+ blendCoroutine = null;
+ yield break;
+ }
+
+ // 메인 카메라의 현재 위치/회전/FOV를 저장 (Cinemachine이 적용한 실제 위치)
+ Camera mainCamera = Camera.main;
+ if (mainCamera == null)
+ {
+ SetImmediate(targetIndex);
+ isBlending = false;
+ blendCoroutine = null;
+ yield break;
+ }
+
+ Vector3 prevCameraPosition = mainCamera.transform.position;
+ Quaternion prevCameraRotation = mainCamera.transform.rotation;
+ float prevCameraFOV = mainCamera.fieldOfView;
+
+ // 블렌드 텍스처 준비
+ EnsurePrevCameraRenderTexture();
+
+ if (prevCameraRenderTexture == null)
+ {
+ SetImmediate(targetIndex);
+ isBlending = false;
+ blendCoroutine = null;
+ yield break;
+ }
+
+ // 블렌드 카메라 준비
+ EnsureBlendCamera();
+ if (blendCamera == null)
+ {
+ SetImmediate(targetIndex);
+ isBlending = false;
+ blendCoroutine = null;
+ yield break;
+ }
+
+ // UI 오버레이 준비
+ var overlay = CameraBlendOverlay.GetOrCreate();
+
// 블렌드 카메라를 이전 카메라 위치로 설정하고 첫 프레임 렌더링
blendCamera.transform.SetPositionAndRotation(prevCameraPosition, prevCameraRotation);
blendCamera.fieldOfView = prevCameraFOV;
blendCamera.targetTexture = prevCameraRenderTexture;
-
- // Camera.Render()로 렌더링 (URP에서도 포스트 프로세싱 적용됨)
blendCamera.Render();
- Graphics.Blit(prevCameraRenderTexture, blendRenderTexture);
- // 실시간 블렌딩 시작 (BlendAmount = 1에서 시작, 이전 카메라가 100% 보임)
- CameraBlendController.StartRealtimeBlend(blendRenderTexture);
- CameraBlendController.BlendAmount = 1f;
+ // UI 오버레이 표시 (알파 1 = 완전 불투명)
+ overlay.Show(prevCameraRenderTexture);
+ overlay.SetAlpha(1f);
// 새 카메라로 전환 (메인 카메라는 이제 새 위치에서 렌더링됨)
SetImmediate(targetIndex);
- // 블렌드 진행: 1 → 0 (이전 카메라 화면이 서서히 사라지고 새 카메라가 드러남)
+ // 블렌드 진행: 알파 1 → 0 (이전 카메라 화면이 서서히 사라짐)
float elapsed = 0f;
while (elapsed < duration)
{
- // 이전 카메라 시점에서 먼저 렌더링 (메인 카메라 렌더링 전에)
+ // 이전 카메라 시점에서 렌더링
blendCamera.transform.SetPositionAndRotation(prevCameraPosition, prevCameraRotation);
blendCamera.fieldOfView = prevCameraFOV;
blendCamera.targetTexture = prevCameraRenderTexture;
-
- // Camera.Render()로 렌더링 (URP에서도 포스트 프로세싱 적용됨)
blendCamera.Render();
- Graphics.Blit(prevCameraRenderTexture, blendRenderTexture);
// 다음 프레임까지 대기
yield return null;
@@ -1115,14 +1106,12 @@ public class CameraManager : MonoBehaviour, IController
float t = Mathf.Clamp01(elapsed / duration);
// 부드러운 이징 적용 (SmoothStep)
t = t * t * (3f - 2f * t);
- // 1에서 0으로: 이전 카메라가 서서히 사라짐
- CameraBlendController.BlendAmount = 1f - t;
+ // 알파를 1에서 0으로: 이전 카메라가 서서히 사라짐
+ overlay.SetAlpha(1f - t);
}
- CameraBlendController.BlendAmount = 0f;
-
// 블렌딩 종료
- CameraBlendController.EndBlend();
+ overlay.Hide();
isBlending = false;
blendCoroutine = null;
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.mat b/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.mat
deleted file mode 100644
index fbcb8667..00000000
--- a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.mat
+++ /dev/null
@@ -1,39 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!21 &2100000
-Material:
- serializedVersion: 8
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_Name: CameraBlend
- m_Shader: {fileID: 4800000, guid: 76944497fc2bcdd479fc435a5d4d8447, type: 3}
- m_Parent: {fileID: 0}
- m_ModifiedSerializedProperties: 0
- m_ValidKeywords: []
- m_InvalidKeywords: []
- m_LightmapFlags: 4
- m_EnableInstancingVariants: 0
- m_DoubleSidedGI: 0
- m_CustomRenderQueue: -1
- stringTagMap: {}
- disabledShaderPasses: []
- m_LockedProperties:
- m_SavedProperties:
- serializedVersion: 3
- m_TexEnvs:
- - _MainTex:
- m_Texture: {fileID: 0}
- m_Scale: {x: 1, y: 1}
- m_Offset: {x: 0, y: 0}
- - _PrevTex:
- m_Texture: {fileID: 0}
- m_Scale: {x: 1, y: 1}
- m_Offset: {x: 0, y: 0}
- m_Ints: []
- m_Floats:
- - _BlendAmount: 0.000075280666
- m_Colors: []
- m_BuildTextureStacks: []
- m_AllowLocking: 1
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.mat.meta b/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.mat.meta
deleted file mode 100644
index c0796a4e..00000000
--- a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.mat.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: f563d7f0c3fc17647ad56388fb936427
-NativeFormatImporter:
- externalObjects: {}
- mainObjectFileID: 0
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.shader b/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.shader
deleted file mode 100644
index 5585439e..00000000
--- a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.shader
+++ /dev/null
@@ -1,57 +0,0 @@
-Shader "Streamingle/CameraBlend"
-{
- Properties
- {
- _PrevTex ("Previous Camera", 2D) = "white" {}
- _BlendAmount ("Blend Amount", Range(0, 1)) = 0
- }
-
- SubShader
- {
- Tags
- {
- "RenderType" = "Opaque"
- "RenderPipeline" = "UniversalPipeline"
- }
-
- Pass
- {
- Name "CameraBlend"
- ZTest Always
- ZWrite Off
- Cull Off
-
- HLSLPROGRAM
- #pragma vertex Vert
- #pragma fragment Frag
-
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
- #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
-
- TEXTURE2D(_PrevTex);
- SAMPLER(sampler_PrevTex);
-
- float _BlendAmount;
-
- float4 Frag(Varyings input) : SV_Target
- {
- float2 uv = input.texcoord;
-
- // 현재 카메라 (Blitter에서 전달됨) - 동일한 샘플러 사용
- float4 currentColor = SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, uv);
-
- // 이전 카메라 (캡처된 텍스처) - 동일한 Linear 샘플러 사용
- float4 prevColor = SAMPLE_TEXTURE2D(_PrevTex, sampler_LinearClamp, uv);
-
- // 리니어 공간에서 블렌딩 (BlendAmount: 1 = 이전, 0 = 현재)
- // 이전 카메라(B)가 위에 덮이고 서서히 사라짐
- float4 finalColor = lerp(currentColor, prevColor, _BlendAmount);
-
- return finalColor;
- }
- ENDHLSL
- }
- }
-
- FallBack Off
-}
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.shader.meta b/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.shader.meta
deleted file mode 100644
index 60cb11b3..00000000
--- a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlend.shader.meta
+++ /dev/null
@@ -1,9 +0,0 @@
-fileFormatVersion: 2
-guid: 76944497fc2bcdd479fc435a5d4d8447
-ShaderImporter:
- externalObjects: {}
- defaultTextures: []
- nonModifiableTextures: []
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlendRendererFeature.cs b/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlendRendererFeature.cs
deleted file mode 100644
index 1a5a7da4..00000000
--- a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlendRendererFeature.cs
+++ /dev/null
@@ -1,290 +0,0 @@
-using UnityEngine;
-using UnityEngine.Rendering;
-using UnityEngine.Rendering.Universal;
-using UnityEngine.Rendering.RenderGraphModule;
-
-///
-/// 카메라 전환 시 크로스 디졸브 블렌딩을 위한 URP Renderer Feature
-/// Unity 6 Render Graph API 사용
-///
-public class CameraBlendRendererFeature : ScriptableRendererFeature
-{
- [System.Serializable]
- public class Settings
- {
- // AfterRenderingPostProcessing - 모든 포스트 프로세싱 적용 후 블렌딩
- public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
- public Material blendMaterial;
- }
-
- public Settings settings = new Settings();
- private CameraBlendRenderPass blendPass;
-
- public override void Create()
- {
- blendPass = new CameraBlendRenderPass(settings);
- blendPass.renderPassEvent = settings.renderPassEvent;
- }
-
- public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
- {
- if (settings.blendMaterial == null)
- return;
-
- // 게임 카메라만 처리
- if (renderingData.cameraData.cameraType != CameraType.Game)
- return;
-
- // 캡처 요청이 있거나 블렌딩 중일 때 패스 추가
- if (CameraBlendController.CaptureRequested ||
- (CameraBlendController.IsBlending && CameraBlendController.BlendTexture != null))
- {
- renderer.EnqueuePass(blendPass);
- }
- }
-
- protected override void Dispose(bool disposing)
- {
- blendPass?.Dispose();
- }
-}
-
-public class CameraBlendRenderPass : ScriptableRenderPass
-{
- private CameraBlendRendererFeature.Settings settings;
- private static readonly int BlendAmountProperty = Shader.PropertyToID("_BlendAmount");
- private static readonly int PrevTexProperty = Shader.PropertyToID("_PrevTex");
-
- private class PassData
- {
- public Material blendMaterial;
- public float blendAmount;
- public RenderTexture blendTexture;
- public TextureHandle sourceTexture;
- public TextureHandle destinationTexture;
- }
-
- private class CapturePassData
- {
- public TextureHandle sourceTexture;
- public RenderTexture targetTexture;
- }
-
- public CameraBlendRenderPass(CameraBlendRendererFeature.Settings settings)
- {
- this.settings = settings;
- profilingSampler = new ProfilingSampler("Camera Blend Pass");
- ConfigureInput(ScriptableRenderPassInput.Color);
- }
-
- public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
- {
- if (settings.blendMaterial == null)
- return;
-
- var resourceData = frameData.Get();
- var cameraData = frameData.Get();
-
- // 백버퍼인 경우 스킵
- if (resourceData.isActiveTargetBackBuffer)
- {
- return;
- }
-
- var source = resourceData.activeColorTexture;
-
- // source가 유효한지 확인
- if (!source.IsValid())
- {
- return;
- }
-
- // 캡처 요청 처리 - 현재 프레임(포스트 프로세싱 적용 후)을 캡처
- if (CameraBlendController.CaptureRequested && CameraBlendController.BlendTexture != null)
- {
- // UnsafePass를 사용하여 RenderTexture에 직접 복사
- using (var builder = renderGraph.AddUnsafePass("Camera Blend Capture", out var captureData, profilingSampler))
- {
- captureData.sourceTexture = source;
- captureData.targetTexture = CameraBlendController.BlendTexture;
-
- builder.UseTexture(source, AccessFlags.Read);
- builder.AllowPassCulling(false);
-
- builder.SetRenderFunc((CapturePassData data, UnsafeGraphContext context) =>
- {
- // NativeCommandBuffer를 통해 Blit 수행
- var nativeCmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd);
- nativeCmd.Blit(data.sourceTexture, data.targetTexture);
- CameraBlendController.CaptureReady = true;
- });
- }
- return; // 캡처만 하고 블렌딩은 다음 프레임부터
- }
-
- // 블렌딩이 활성화되지 않았으면 스킵
- if (!CameraBlendController.IsBlending || CameraBlendController.BlendTexture == null)
- return;
-
- // cameraColorDesc 사용 - 카메라 색상 텍스처 설명자
- var cameraTargetDesc = renderGraph.GetTextureDesc(resourceData.cameraColor);
- cameraTargetDesc.name = "_CameraBlendDestination";
- cameraTargetDesc.clearBuffer = false;
- var destination = renderGraph.CreateTexture(cameraTargetDesc);
-
- // 블렌딩 패스
- using (var builder = renderGraph.AddRasterRenderPass("Camera Blend", out var passData, profilingSampler))
- {
- passData.blendMaterial = settings.blendMaterial;
- passData.blendAmount = CameraBlendController.BlendAmount;
- passData.blendTexture = CameraBlendController.BlendTexture;
- passData.sourceTexture = source;
-
- builder.UseTexture(source, AccessFlags.Read);
- builder.SetRenderAttachment(destination, 0, AccessFlags.Write);
- builder.AllowPassCulling(false);
-
- builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
- {
- data.blendMaterial.SetFloat(BlendAmountProperty, data.blendAmount);
- data.blendMaterial.SetTexture(PrevTexProperty, data.blendTexture);
- Blitter.BlitTexture(context.cmd, data.sourceTexture, new Vector4(1, 1, 0, 0), data.blendMaterial, 0);
- });
- }
-
- // 결과를 source로 복사
- using (var builder = renderGraph.AddRasterRenderPass("Camera Blend Copy Back", out var copyData, profilingSampler))
- {
- copyData.sourceTexture = destination;
-
- builder.UseTexture(destination, AccessFlags.Read);
- builder.SetRenderAttachment(source, 0, AccessFlags.Write);
- builder.AllowPassCulling(false);
-
- builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
- {
- Blitter.BlitTexture(context.cmd, data.sourceTexture, new Vector4(1, 1, 0, 0), 0, false);
- });
- }
- }
-
- [System.Obsolete("This rendering path is for compatibility mode only (when Render Graph is disabled). Use Render Graph API instead.", false)]
- public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
- {
- // Legacy path
- }
-
- public void Dispose()
- {
- }
-}
-
-///
-/// 카메라 블렌딩을 제어하는 정적 컨트롤러
-///
-public static class CameraBlendController
-{
- private static bool isBlending = false;
- private static float blendAmount = 1f;
- private static RenderTexture blendTexture;
- private static bool captureRequested = false;
- private static bool captureReady = false;
- private static bool isRealtimeMode = false;
-
- public static bool IsBlending
- {
- get => isBlending;
- set => isBlending = value;
- }
-
- public static float BlendAmount
- {
- get => blendAmount;
- set => blendAmount = Mathf.Clamp01(value);
- }
-
- public static RenderTexture BlendTexture
- {
- get => blendTexture;
- set => blendTexture = value;
- }
-
- public static bool CaptureRequested
- {
- get => captureRequested;
- set => captureRequested = value;
- }
-
- public static bool CaptureReady
- {
- get => captureReady;
- set => captureReady = value;
- }
-
- public static bool IsRealtimeMode
- {
- get => isRealtimeMode;
- set => isRealtimeMode = value;
- }
-
- ///
- /// 다음 프레임에서 현재 화면을 캡처하도록 요청합니다. (스냅샷 모드)
- ///
- public static void RequestCapture(RenderTexture targetTexture)
- {
- blendTexture = targetTexture;
- captureRequested = true;
- captureReady = false;
- isRealtimeMode = false;
- }
-
- ///
- /// 캡처가 완료된 후 블렌딩을 시작합니다. (스냅샷 모드)
- /// BlendAmount = 1에서 시작 (이전 카메라 100% 보임)
- ///
- public static void StartBlendAfterCapture()
- {
- if (captureReady && blendTexture != null)
- {
- blendAmount = 1f;
- isBlending = true;
- captureRequested = false;
- }
- }
-
- ///
- /// 실시간 블렌딩을 시작합니다. (매 프레임 이전 카메라 렌더링)
- /// BlendAmount = 1에서 시작 (이전 카메라 100% 보임)
- ///
- public static void StartRealtimeBlend(RenderTexture texture)
- {
- blendTexture = texture;
- blendAmount = 1f;
- isBlending = true;
- isRealtimeMode = true;
- captureRequested = false;
- captureReady = false;
- }
-
- public static void StartBlend(RenderTexture texture)
- {
- blendTexture = texture;
- blendAmount = 0f;
- isBlending = true;
- }
-
- public static void EndBlend()
- {
- isBlending = false;
- blendAmount = 1f;
- blendTexture = null;
- captureRequested = false;
- captureReady = false;
- isRealtimeMode = false;
- }
-
- public static void Reset()
- {
- EndBlend();
- }
-}
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlendRendererFeature.cs.meta b/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlendRendererFeature.cs.meta
deleted file mode 100644
index c1c2037b..00000000
--- a/Assets/Scripts/Streamingle/StreamingleControl/Rendering/CameraBlendRendererFeature.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: 14b4e395bb7cf744d87b2c1885014709
\ No newline at end of file
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/Rendering.meta b/Assets/Scripts/Streamingle/StreamingleControl/UI.meta
similarity index 77%
rename from Assets/Scripts/Streamingle/StreamingleControl/Rendering.meta
rename to Assets/Scripts/Streamingle/StreamingleControl/UI.meta
index fb98b7ed..feb434a9 100644
--- a/Assets/Scripts/Streamingle/StreamingleControl/Rendering.meta
+++ b/Assets/Scripts/Streamingle/StreamingleControl/UI.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 634dec0a07bb460468b7e86f02bbc5b9
+guid: 055b59bee33be324c88ea76f3ea4786b
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Assets/Scripts/Streamingle/StreamingleControl/UI/CameraBlendOverlay.cs b/Assets/Scripts/Streamingle/StreamingleControl/UI/CameraBlendOverlay.cs
new file mode 100644
index 00000000..a1d3375c
--- /dev/null
+++ b/Assets/Scripts/Streamingle/StreamingleControl/UI/CameraBlendOverlay.cs
@@ -0,0 +1,126 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Streamingle
+{
+ ///
+ /// 카메라 블렌딩용 UI 오버레이
+ /// RawImage 하나로 이전 카메라 화면을 표시하고 서서히 사라지게 함
+ ///
+ public class CameraBlendOverlay : MonoBehaviour
+ {
+ private static CameraBlendOverlay instance;
+ public static CameraBlendOverlay Instance => instance;
+
+ private Canvas canvas;
+ private RawImage rawImage;
+ private CanvasGroup canvasGroup;
+
+ private void Awake()
+ {
+ if (instance != null && instance != this)
+ {
+ Destroy(gameObject);
+ return;
+ }
+ instance = this;
+ DontDestroyOnLoad(gameObject);
+
+ SetupUI();
+ }
+
+ private void SetupUI()
+ {
+ // Canvas 설정
+ canvas = gameObject.AddComponent