2026-04-20 02:05:17 +08:00
|
|
|
using System;
|
|
|
|
|
using XCEngine;
|
|
|
|
|
using XCEngine.Rendering;
|
|
|
|
|
|
|
|
|
|
namespace XCEngine.Rendering.Universal
|
|
|
|
|
{
|
|
|
|
|
public abstract class RendererBackedRenderPipelineAsset
|
|
|
|
|
: ScriptableRenderPipelineAsset
|
|
|
|
|
{
|
|
|
|
|
public ScriptableRendererData[] rendererDataList =
|
|
|
|
|
Array.Empty<ScriptableRendererData>();
|
|
|
|
|
public int defaultRendererIndex = 0;
|
2026-04-20 15:03:45 +08:00
|
|
|
private int m_rendererDataRuntimeStateHash;
|
|
|
|
|
private bool m_rendererDataRuntimeStateHashResolved;
|
2026-04-20 02:05:17 +08:00
|
|
|
|
|
|
|
|
protected RendererBackedRenderPipelineAsset()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override ScriptableRenderPipeline CreatePipeline()
|
|
|
|
|
{
|
|
|
|
|
return CreateRendererBackedPipeline();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void ConfigureCameraRenderRequest(
|
|
|
|
|
CameraRenderRequestContext context)
|
|
|
|
|
{
|
|
|
|
|
ConfigureRendererCameraRequest(
|
|
|
|
|
new RendererCameraRequestContext(context));
|
|
|
|
|
|
|
|
|
|
ScriptableRendererData resolvedRendererData =
|
2026-04-20 15:03:45 +08:00
|
|
|
ResolveSelectedRendererData();
|
2026-04-20 02:05:17 +08:00
|
|
|
if (resolvedRendererData != null)
|
|
|
|
|
{
|
|
|
|
|
resolvedRendererData
|
|
|
|
|
.ConfigureCameraRenderRequestInstance(
|
|
|
|
|
context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void ConfigureCameraFramePlan(
|
|
|
|
|
ScriptableRenderPipelinePlanningContext context)
|
|
|
|
|
{
|
|
|
|
|
ScriptableRendererData resolvedRendererData =
|
2026-04-20 15:03:45 +08:00
|
|
|
ResolveSelectedRendererData();
|
2026-04-20 02:05:17 +08:00
|
|
|
if (resolvedRendererData != null)
|
|
|
|
|
{
|
|
|
|
|
resolvedRendererData
|
|
|
|
|
.ConfigureCameraFramePlanInstance(
|
|
|
|
|
context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override string GetPipelineRendererAssetKey()
|
|
|
|
|
{
|
|
|
|
|
ScriptableRendererData resolvedRendererData =
|
2026-04-20 15:03:45 +08:00
|
|
|
ResolveSelectedRendererData();
|
2026-04-20 02:05:17 +08:00
|
|
|
return resolvedRendererData != null
|
|
|
|
|
? resolvedRendererData
|
|
|
|
|
.GetPipelineRendererAssetKeyInstance()
|
|
|
|
|
: string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void ReleaseRuntimeResources()
|
|
|
|
|
{
|
|
|
|
|
ReleaseRendererDataRuntimeResources();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-20 15:03:45 +08:00
|
|
|
protected override void SynchronizeRuntimeResourceVersion()
|
|
|
|
|
{
|
|
|
|
|
int runtimeStateHash =
|
|
|
|
|
ComputeRendererDataRuntimeStateHash();
|
|
|
|
|
if (!m_rendererDataRuntimeStateHashResolved)
|
|
|
|
|
{
|
|
|
|
|
m_rendererDataRuntimeStateHash =
|
|
|
|
|
runtimeStateHash;
|
|
|
|
|
m_rendererDataRuntimeStateHashResolved = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (runtimeStateHash ==
|
|
|
|
|
m_rendererDataRuntimeStateHash)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_rendererDataRuntimeStateHash =
|
|
|
|
|
runtimeStateHash;
|
|
|
|
|
SetDirty();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-20 02:05:17 +08:00
|
|
|
protected virtual ScriptableRenderPipeline
|
|
|
|
|
CreateRendererBackedPipeline()
|
|
|
|
|
{
|
|
|
|
|
return new RendererBackedRenderPipeline(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void ConfigureRendererCameraRequest(
|
|
|
|
|
RendererCameraRequestContext context)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual ScriptableRendererData
|
|
|
|
|
CreateDefaultRendererData()
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal ScriptableRendererData GetDefaultRendererData()
|
|
|
|
|
{
|
2026-04-20 15:03:45 +08:00
|
|
|
return ResolveSelectedRendererData();
|
2026-04-20 02:05:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal ScriptableRenderer GetDefaultRenderer()
|
|
|
|
|
{
|
2026-04-20 15:03:45 +08:00
|
|
|
return ResolveSelectedRenderer();
|
2026-04-20 02:05:17 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-20 15:03:45 +08:00
|
|
|
internal ScriptableRendererData ResolveSelectedRendererData()
|
2026-04-20 02:05:17 +08:00
|
|
|
{
|
2026-04-20 15:03:45 +08:00
|
|
|
return ResolveRendererDataByResolvedIndex(
|
|
|
|
|
ResolveSelectedRendererIndex());
|
|
|
|
|
}
|
2026-04-20 02:05:17 +08:00
|
|
|
|
2026-04-20 15:03:45 +08:00
|
|
|
internal ScriptableRenderer ResolveSelectedRenderer()
|
|
|
|
|
{
|
|
|
|
|
ScriptableRendererData rendererData =
|
|
|
|
|
ResolveSelectedRendererData();
|
|
|
|
|
return rendererData != null
|
|
|
|
|
? rendererData.GetRendererInstance()
|
|
|
|
|
: null;
|
|
|
|
|
}
|
2026-04-20 02:05:17 +08:00
|
|
|
|
2026-04-20 15:03:45 +08:00
|
|
|
internal ScriptableRendererData GetRendererData(
|
|
|
|
|
int rendererIndex)
|
|
|
|
|
{
|
|
|
|
|
return ResolveRendererDataByResolvedIndex(
|
|
|
|
|
ResolveRendererIndex(rendererIndex));
|
2026-04-20 02:05:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal ScriptableRenderer GetRenderer(
|
|
|
|
|
int rendererIndex)
|
|
|
|
|
{
|
|
|
|
|
ScriptableRendererData rendererData =
|
|
|
|
|
GetRendererData(rendererIndex);
|
|
|
|
|
return rendererData != null
|
|
|
|
|
? rendererData.GetRendererInstance()
|
|
|
|
|
: null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected internal void ReleaseRendererDataRuntimeResources()
|
|
|
|
|
{
|
|
|
|
|
EnsureRendererDataList();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < rendererDataList.Length; ++i)
|
|
|
|
|
{
|
|
|
|
|
ScriptableRendererData rendererData =
|
|
|
|
|
rendererDataList[i];
|
|
|
|
|
if (rendererData == null ||
|
|
|
|
|
WasRendererDataReleasedEarlier(i))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rendererData.ReleaseRuntimeResourcesInstance();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void EnsureRendererDataList()
|
|
|
|
|
{
|
|
|
|
|
if (rendererDataList != null &&
|
|
|
|
|
rendererDataList.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScriptableRendererData defaultRendererData =
|
|
|
|
|
CreateDefaultRendererData();
|
|
|
|
|
rendererDataList =
|
|
|
|
|
defaultRendererData != null
|
|
|
|
|
? new ScriptableRendererData[]
|
|
|
|
|
{
|
|
|
|
|
defaultRendererData
|
|
|
|
|
}
|
|
|
|
|
: Array.Empty<ScriptableRendererData>();
|
|
|
|
|
defaultRendererIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool WasRendererDataReleasedEarlier(
|
|
|
|
|
int rendererDataIndex)
|
|
|
|
|
{
|
|
|
|
|
ScriptableRendererData rendererData =
|
|
|
|
|
rendererDataList[rendererDataIndex];
|
|
|
|
|
for (int i = 0; i < rendererDataIndex; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (object.ReferenceEquals(
|
|
|
|
|
rendererDataList[i],
|
|
|
|
|
rendererData))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-20 15:03:45 +08:00
|
|
|
private int ComputeRendererDataRuntimeStateHash()
|
|
|
|
|
{
|
|
|
|
|
unchecked
|
|
|
|
|
{
|
|
|
|
|
int hash = 17;
|
|
|
|
|
hash =
|
|
|
|
|
(hash * 31) +
|
|
|
|
|
ResolveSelectedRendererIndex();
|
|
|
|
|
if (rendererDataList == null)
|
|
|
|
|
{
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hash = (hash * 31) + rendererDataList.Length;
|
|
|
|
|
for (int i = 0; i < rendererDataList.Length; ++i)
|
|
|
|
|
{
|
|
|
|
|
ScriptableRendererData rendererData =
|
|
|
|
|
rendererDataList[i];
|
|
|
|
|
if (rendererData != null)
|
|
|
|
|
{
|
|
|
|
|
hash =
|
|
|
|
|
(hash * 31) +
|
|
|
|
|
rendererData
|
|
|
|
|
.GetRuntimeStateVersionInstance();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ScriptableRendererData ResolveRendererDataByResolvedIndex(
|
|
|
|
|
int resolvedRendererIndex)
|
|
|
|
|
{
|
|
|
|
|
EnsureRendererDataList();
|
|
|
|
|
if (resolvedRendererIndex < 0)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rendererDataList[resolvedRendererIndex] == null)
|
|
|
|
|
{
|
|
|
|
|
rendererDataList[resolvedRendererIndex] =
|
|
|
|
|
CreateDefaultRendererData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rendererDataList[resolvedRendererIndex];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int ResolveSelectedRendererIndex()
|
|
|
|
|
{
|
|
|
|
|
return ResolveRendererIndex(defaultRendererIndex);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-20 02:05:17 +08:00
|
|
|
private int ResolveRendererIndex(
|
|
|
|
|
int rendererIndex)
|
|
|
|
|
{
|
|
|
|
|
EnsureRendererDataList();
|
|
|
|
|
if (rendererDataList.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rendererIndex < 0 ||
|
|
|
|
|
rendererIndex >= rendererDataList.Length)
|
|
|
|
|
{
|
|
|
|
|
return ResolveDefaultRendererIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rendererIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int ResolveDefaultRendererIndex()
|
|
|
|
|
{
|
|
|
|
|
EnsureRendererDataList();
|
|
|
|
|
if (rendererDataList.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (defaultRendererIndex < 0 ||
|
|
|
|
|
defaultRendererIndex >= rendererDataList.Length)
|
|
|
|
|
{
|
|
|
|
|
defaultRendererIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return defaultRendererIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|