Fix mobile render texture black screens
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using DG.Tweening;
|
||||
using Yarn.Unity;
|
||||
using AibisDream.Framework;
|
||||
using Cinemachine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UI;
|
||||
using AibisDream.Kit;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
@@ -64,12 +66,14 @@ namespace AibisDream.FixSystem
|
||||
|
||||
[SerializeField] private Material fadeMaterial;
|
||||
private Material runtimeMemoryMaterial;
|
||||
private readonly List<RenderTexture> runtimeRenderTextures = new();
|
||||
|
||||
public void OpenMemoryView()
|
||||
{
|
||||
memoryGroup.SetActive(true);
|
||||
memoryView.gameObject.SetActive(true);
|
||||
|
||||
EnsureMemoryRenderTargets();
|
||||
StartCoroutine(PrimeMemoryRenderTargets());
|
||||
}
|
||||
|
||||
public IEnumerator DropMemoryProjector()
|
||||
@@ -176,6 +180,114 @@ namespace AibisDream.FixSystem
|
||||
{
|
||||
if (runtimeMemoryMaterial != null)
|
||||
Destroy(runtimeMemoryMaterial);
|
||||
|
||||
foreach (var renderTexture in runtimeRenderTextures)
|
||||
{
|
||||
if (renderTexture == null)
|
||||
continue;
|
||||
|
||||
renderTexture.Release();
|
||||
Destroy(renderTexture);
|
||||
}
|
||||
runtimeRenderTextures.Clear();
|
||||
}
|
||||
|
||||
private void EnsureMemoryRenderTargets()
|
||||
{
|
||||
if (memoryGroup == null || memoryView == null)
|
||||
return;
|
||||
|
||||
var cameras = memoryGroup.GetComponentsInChildren<Camera>(true);
|
||||
foreach (var renderCamera in cameras)
|
||||
{
|
||||
if (renderCamera == null || renderCamera.targetTexture == null)
|
||||
continue;
|
||||
|
||||
renderCamera.allowHDR = false;
|
||||
renderCamera.allowMSAA = false;
|
||||
|
||||
var originalTexture = renderCamera.targetTexture;
|
||||
var targetTexture = originalTexture;
|
||||
if (ShouldReplaceRenderTexture(originalTexture))
|
||||
{
|
||||
targetTexture = CreateCompatibleRenderTexture(originalTexture);
|
||||
renderCamera.targetTexture = targetTexture;
|
||||
RebindMemoryRawImages(originalTexture, targetTexture);
|
||||
}
|
||||
|
||||
if (!targetTexture.IsCreated())
|
||||
{
|
||||
targetTexture.Create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ShouldReplaceRenderTexture(RenderTexture renderTexture)
|
||||
{
|
||||
if (renderTexture == null)
|
||||
return true;
|
||||
|
||||
if (!SystemInfo.SupportsRenderTextureFormat(renderTexture.format))
|
||||
return true;
|
||||
|
||||
var maxSize = Mathf.Min(SystemInfo.maxTextureSize, 2048);
|
||||
return renderTexture.width > maxSize || renderTexture.height > maxSize;
|
||||
}
|
||||
|
||||
private RenderTexture CreateCompatibleRenderTexture(RenderTexture source)
|
||||
{
|
||||
var maxSize = Mathf.Min(SystemInfo.maxTextureSize, 2048);
|
||||
var sourceWidth = source != null ? source.width : Screen.width;
|
||||
var sourceHeight = source != null ? source.height : Screen.height;
|
||||
var scale = Mathf.Min(1f, maxSize / (float)Mathf.Max(sourceWidth, sourceHeight));
|
||||
var width = Mathf.Max(1, Mathf.RoundToInt(sourceWidth * scale));
|
||||
var height = Mathf.Max(1, Mathf.RoundToInt(sourceHeight * scale));
|
||||
|
||||
var renderTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32)
|
||||
{
|
||||
name = source != null ? $"{source.name}_RuntimeCompatible" : "Memory_RuntimeCompatible",
|
||||
antiAliasing = 1,
|
||||
useMipMap = false,
|
||||
autoGenerateMips = false
|
||||
};
|
||||
renderTexture.Create();
|
||||
runtimeRenderTextures.Add(renderTexture);
|
||||
return renderTexture;
|
||||
}
|
||||
|
||||
private void RebindMemoryRawImages(Texture oldTexture, Texture newTexture)
|
||||
{
|
||||
var rawImages = memoryView.GetComponentsInChildren<RawImage>(true);
|
||||
foreach (var rawImage in rawImages)
|
||||
{
|
||||
if (rawImage != null && rawImage.texture == oldTexture)
|
||||
{
|
||||
rawImage.texture = newTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator PrimeMemoryRenderTargets()
|
||||
{
|
||||
yield return null;
|
||||
ForceRenderMemoryTargets();
|
||||
yield return new WaitForEndOfFrame();
|
||||
ForceRenderMemoryTargets();
|
||||
}
|
||||
|
||||
private void ForceRenderMemoryTargets()
|
||||
{
|
||||
if (memoryGroup == null || !memoryGroup.activeInHierarchy)
|
||||
return;
|
||||
|
||||
var cameras = memoryGroup.GetComponentsInChildren<Camera>(true);
|
||||
foreach (var renderCamera in cameras)
|
||||
{
|
||||
if (renderCamera != null && renderCamera.enabled && renderCamera.targetTexture != null)
|
||||
{
|
||||
renderCamera.Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckAllFound()
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace AibisDream
|
||||
private EyeData _eyeData = new();
|
||||
private Tween hsvShiftTween;
|
||||
private MouseFollowAndZoom mouseFollowAndZoom;
|
||||
private RenderTexture runtimeEyeRenderTexture;
|
||||
|
||||
/// <summary>
|
||||
/// 眼睛 RawImage 的故障/色相/饱和度等效果依赖 AllIn1SpriteShader(或兼容)材质上的属性。
|
||||
@@ -82,6 +83,88 @@ namespace AibisDream
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnsureEyeViewRenderTarget()
|
||||
{
|
||||
if (eyeImage == null)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] eyeImage 未赋值,无法显示视觉模块画面。", this);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cameraManager == null)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] cameraManager 未赋值,无法渲染视觉模块画面。", this);
|
||||
return false;
|
||||
}
|
||||
|
||||
var viewCamera = cameraManager.GetComponent<Camera>();
|
||||
if (viewCamera == null)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] cameraManager 上未找到 Camera 组件,无法渲染视觉模块画面。", cameraManager);
|
||||
return false;
|
||||
}
|
||||
|
||||
viewCamera.allowHDR = false;
|
||||
viewCamera.allowMSAA = false;
|
||||
|
||||
var renderTexture = viewCamera.targetTexture;
|
||||
if (renderTexture == null)
|
||||
{
|
||||
renderTexture = CreateRuntimeEyeRenderTexture();
|
||||
viewCamera.targetTexture = renderTexture;
|
||||
}
|
||||
|
||||
if (!renderTexture.IsCreated())
|
||||
{
|
||||
renderTexture.Create();
|
||||
}
|
||||
|
||||
if (eyeImage.texture != renderTexture)
|
||||
{
|
||||
eyeImage.texture = renderTexture;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private RenderTexture CreateRuntimeEyeRenderTexture()
|
||||
{
|
||||
var width = Mathf.Clamp(Screen.width, 1, 2048);
|
||||
var height = Mathf.Clamp(Screen.height, 1, 2048);
|
||||
|
||||
runtimeEyeRenderTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32)
|
||||
{
|
||||
name = "Runtime Eye View RenderTexture",
|
||||
antiAliasing = 1,
|
||||
useMipMap = false,
|
||||
autoGenerateMips = false
|
||||
};
|
||||
runtimeEyeRenderTexture.Create();
|
||||
return runtimeEyeRenderTexture;
|
||||
}
|
||||
|
||||
private IEnumerator PrimeEyeViewRender()
|
||||
{
|
||||
yield return null;
|
||||
ForceRenderEyeView();
|
||||
yield return new WaitForEndOfFrame();
|
||||
ForceRenderEyeView();
|
||||
}
|
||||
|
||||
private void ForceRenderEyeView()
|
||||
{
|
||||
if (cameraManager == null || !cameraManager.gameObject.activeInHierarchy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var viewCamera = cameraManager.GetComponent<Camera>();
|
||||
if (viewCamera != null && viewCamera.enabled && viewCamera.targetTexture != null)
|
||||
{
|
||||
viewCamera.Render();
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
FixSystemCenter.SystemDic.Register(this);
|
||||
@@ -119,11 +202,15 @@ namespace AibisDream
|
||||
{
|
||||
cameraManager.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
EnsureEyeViewRenderTarget();
|
||||
|
||||
mouseFollowAndZoom.SetIsActive(true);
|
||||
mouseFollowAndZoom.SetIsLock(false);
|
||||
// 激活 ViewCamera 后再打开 EyeView
|
||||
OpenEyeView();
|
||||
ForceRenderEyeView();
|
||||
StartCoroutine(PrimeEyeViewRender());
|
||||
// 进入视图时的逻辑
|
||||
Debug.Log("EyeView entered.");
|
||||
}
|
||||
@@ -168,6 +255,16 @@ namespace AibisDream
|
||||
Debug.Log("EyeView exited.");
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (runtimeEyeRenderTexture != null)
|
||||
{
|
||||
runtimeEyeRenderTexture.Release();
|
||||
Destroy(runtimeEyeRenderTexture);
|
||||
runtimeEyeRenderTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
SetEyeColorState(_eyeData.currentState);
|
||||
|
||||
Reference in New Issue
Block a user