First Commit

This commit is contained in:
2025-05-18 22:39:39 +03:00
commit 042ede7228
440 changed files with 103153 additions and 0 deletions

View File

@@ -0,0 +1,310 @@
using System;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.XR;
namespace Golems
{
/// <summary>
/// Creates a bunch of named RenderTexture for the camera that can then be used by other
/// render passes.
/// The textures can be used, for example, as a temporary texture when operating on the
/// camera colour texture and then copying it back - saving the pass having to create
/// its own texture. Another example is that the textures can be used to pass result between
/// passes - since these temporary textures will be around from the time they are created to
/// the end of the render pipeline.
///
/// Other passes should access the textures via the static interface this class
/// provides.
///
/// NOTE: names are converted to integer hashes to save doing string operations every frame.
/// </summary>
public class TemporaryCameraCopyTextureRenderFeature : ScriptableRendererFeature
{
[SerializeField]
private RenderPassEvent m_WhenToAdd = RenderPassEvent.BeforeRendering;
[SerializeField]
private List<string> m_TextureNames;
private TemporaryCameraTextureRenderPass m_Pass;
private readonly Dictionary<int, RenderTargetIdentifier> m_NameHashToTargetIdentifierMap =
new Dictionary<int, RenderTargetIdentifier>();
private readonly List<NameHashShaderIdPair> m_NameHashesAndIds = new List<NameHashShaderIdPair>();
public struct NameHashShaderIdPair
{
public int m_NameHash;
public int m_ShaderId;
}
public override void Create()
{
if (s_HasInstance && s_Instance != null)
{
return;
}
s_HasInstance = true;
s_Instance = this;
//
// Create the name hashes
//
m_NameHashesAndIds.Clear();
for (int i = 0; i < m_TextureNames.Count; i++)
{
m_NameHashesAndIds.Add( new NameHashShaderIdPair()
{
m_NameHash = GetNameHash(m_TextureNames[i]),
m_ShaderId = Shader.PropertyToID(m_TextureNames[i]),
});
}
m_Pass = new TemporaryCameraTextureRenderPass();
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (m_Pass == null)
{
return;
}
#if ENABLE_VR
var isXR = XRSettings.enabled;
m_Pass.Setup(m_WhenToAdd, isXR, m_NameHashesAndIds, SetupTempTargetIdentifier, ClearTempTargetIdentifiers);
#else
m_Pass.Setup(m_WhenToAdd, false, m_NameHashesAndIds, SetupTempTargetIdentifier, ClearTempTargetIdentifiers);
#endif
renderer.EnqueuePass(m_Pass);
}
protected override void Dispose(bool disposing)
{
if (s_Instance == this)
{
s_HasInstance = false;
s_Instance = null;
}
base.Dispose(disposing);
}
private bool InternalTryGetTempTextureIdentifier(int nameHash, out RenderTargetIdentifier outTargetIdentifier)
{
return m_NameHashToTargetIdentifierMap.TryGetValue(nameHash, out outTargetIdentifier);
}
private void InternalClearTempTargetIdentifiers()
{
m_NameHashToTargetIdentifierMap.Clear();
}
private void InternalSetupTempTargetIdentifier(int nameHash, RenderTargetIdentifier identifier)
{
m_NameHashToTargetIdentifierMap[nameHash] = identifier;
}
//
//
// Static interface
//
//
public const int k_InvalidNameHash = -1;
private static bool s_HasInstance;
private static TemporaryCameraCopyTextureRenderFeature s_Instance;
/// <summary>
/// Used by passes to ask for a named texture by its name hash.
/// NOTE: hashes are used to avoid having a dictionary keyed by strings.
/// </summary>
/// <param name="nameHash"></param>
/// <param name="outTargetIdentifier"></param>
/// <returns>true if the texture is available, false otherwise</returns>
public static bool TryGetTempTextureIdentifier(int nameHash, out RenderTargetIdentifier outTargetIdentifier)
{
if (!s_HasInstance)
{
outTargetIdentifier = default;
return false;
}
return s_Instance.InternalTryGetTempTextureIdentifier(nameHash, out outTargetIdentifier);
}
/// <summary>
/// Given a name, this returns the hash of that name.
/// </summary>
public static int GetNameHash(string name)
{
if (string.IsNullOrEmpty(name))
{
return k_InvalidNameHash;
}
return name.GetHashCode();
}
private static void SetupTempTargetIdentifier(int nameHash, RenderTargetIdentifier identifier)
{
if (!s_HasInstance)
{
return;
}
s_Instance.InternalSetupTempTargetIdentifier(nameHash, identifier);
}
private static void ClearTempTargetIdentifiers()
{
if (!s_HasInstance)
{
return;
}
s_Instance.InternalClearTempTargetIdentifiers();
}
#if UNITY_EDITOR
private bool m_EditorNameHashToTargetIdentifierMapFoldout;
private bool m_EditorNameHashesAndIdsFoldout;
protected virtual void EditorOnInspectorGUIAfterBase()
{
EditorGUILayout.LabelField("Info", EditorStyles.boldLabel);
var origIndent = EditorGUI.indentLevel;
EditorGUI.indentLevel += 1;
#if false
//
// NOTE:
// m_NameHashToTargetIdentifierMap gets cleared every frame so no useful info
//
m_EditorNameHashToTargetIdentifierMapFoldout = EditorGUILayout.Foldout(m_EditorNameHashToTargetIdentifierMapFoldout, "Name hash to identifier map");
if (m_EditorNameHashToTargetIdentifierMapFoldout)
{
foreach (var nameHashIdentifier in m_NameHashToTargetIdentifierMap)
{
EditorGUILayout.LabelField(
$"Name hash: {nameHashIdentifier.Key}, identifier {nameHashIdentifier.Value}");
}
}
#endif
m_EditorNameHashesAndIdsFoldout = EditorGUILayout.Foldout(m_EditorNameHashesAndIdsFoldout, "Name hash to shader id map");
if (m_EditorNameHashesAndIdsFoldout)
{
foreach (var nameHashIds in m_NameHashesAndIds)
{
EditorGUILayout.LabelField(
$"Name hash: {nameHashIds.m_NameHash}, identifier {nameHashIds.m_ShaderId}");
}
}
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("Instance", s_Instance, typeof(TemporaryCameraCopyTextureRenderFeature), false);
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel = origIndent;
EditorGUILayout.LabelField("Controls", EditorStyles.boldLabel);
}
private static void EditorTextureNameAndHash(string label, string namedTemporaryName, int namedTemporaryNameHash)
{
EditorGUILayout.TextField(label);
EditorGUI.indentLevel += 1;
if (!string.IsNullOrEmpty(namedTemporaryName))
{
EditorGUILayout.IntField(namedTemporaryName, namedTemporaryNameHash);
}
else
{
EditorGUILayout.IntField("null name", namedTemporaryNameHash);
}
EditorGUI.indentLevel -= 1;
}
[CustomEditor(typeof(TemporaryCameraCopyTextureRenderFeature))]
private class TemporaryCameraCopyTextureRenderFeatureEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var me = target as TemporaryCameraCopyTextureRenderFeature;
if (me != null)
{
me.EditorOnInspectorGUIAfterBase();
}
}
}
#endif
}
/// <summary>
/// This is the pass that creates the named textures.
/// </summary>
public class TemporaryCameraTextureRenderPass : ScriptableRenderPass
{
private bool m_IsXR;
private List<TemporaryCameraCopyTextureRenderFeature.NameHashShaderIdPair> m_NameHashesAndIds;
private Action<int, RenderTargetIdentifier> m_SetIdentifierAction;
private Action m_ClearIdentifiersAction;
public void Setup(RenderPassEvent whenToRender, bool isXR,
List<TemporaryCameraCopyTextureRenderFeature.NameHashShaderIdPair> nameHashesAndIds, Action<int, RenderTargetIdentifier> setIdentifierAction,
Action clearIdentifiersAction)
{
renderPassEvent = whenToRender;
m_IsXR = isXR;
m_NameHashesAndIds = nameHashesAndIds;
m_SetIdentifierAction = setIdentifierAction;
m_ClearIdentifiersAction = clearIdentifiersAction;
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
//
// Create the temporary textures
//
#if UNITY_SWITCH
var renderTextureDescriptor = renderingData.cameraData.cameraTargetDescriptor;
var width = 1280;
var height = 720;
#elif ENABLE_VR
var renderTextureDescriptor = m_IsXR ? XRSettings.eyeTextureDesc : renderingData.cameraData.cameraTargetDescriptor;
#else
var renderTextureDescriptor = renderingData.cameraData.cameraTargetDescriptor;
#endif
for (int i = 0; i < m_NameHashesAndIds.Count; i++)
{
#if UNITY_SWITCH
cmd.GetTemporaryRT(m_NameHashesAndIds[i].m_ShaderId, width,height,renderTextureDescriptor.depthBufferBits,FilterMode.Bilinear,renderTextureDescriptor.colorFormat);
#else
cmd.GetTemporaryRT(m_NameHashesAndIds[i].m_ShaderId, renderTextureDescriptor);
#endif
m_SetIdentifierAction?.Invoke(m_NameHashesAndIds[i].m_NameHash, new RenderTargetIdentifier(m_NameHashesAndIds[i].m_ShaderId));
}
}
public override void OnCameraCleanup(CommandBuffer cmd)
{
m_ClearIdentifiersAction?.Invoke();
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 45f2fc87cae84acca393898ba15c1861
timeCreated: 1645691226