First Commit
This commit is contained in:
@@ -0,0 +1,323 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.XR;
|
||||
|
||||
namespace Golems.RenderFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for RenderFeatures that take a source and do some operation on it and put
|
||||
/// the result into some destination.
|
||||
/// This base class provides settings for the source and destination textures via
|
||||
/// RenderFeatures.TextureSourceType, allowing the named temporary texture name to be given
|
||||
/// if need (named textures are provided by TemporaryCameraCopyTextureRenderFeature).
|
||||
/// Can also set a named textures as a temporary copy texture if the source and destination
|
||||
/// are the same.
|
||||
/// </summary>
|
||||
public abstract class SourceToDestinationBlitRenderFeature : ScriptableRendererFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// The texture source type of the source of the pass.
|
||||
/// Camera colour or named temporary texture.
|
||||
/// </summary>
|
||||
[Header("Source and Destination")]
|
||||
[SerializeField]
|
||||
protected RenderFeatures.TextureSourceType m_SourceTextureSourceType = RenderFeatures.TextureSourceType.CameraColour;
|
||||
|
||||
/// <summary>
|
||||
/// If the source is a named texture then this is its name.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private string m_SourceNamedTemporaryName;
|
||||
|
||||
protected int m_SourceNamedTemporaryNameHash;
|
||||
|
||||
/// <summary>
|
||||
/// The texture source type of the destination of the pass.
|
||||
/// Camera colour or named temporary texture.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
protected RenderFeatures.TextureSourceType m_DestinationTextureSourceType = RenderFeatures.TextureSourceType.CameraColour;
|
||||
|
||||
/// <summary>
|
||||
/// If the destination is a named texture then this is its name.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private string m_DestinationNamedTemporaryName;
|
||||
|
||||
protected int m_DestinationNamedTemporaryNameHash;
|
||||
|
||||
/// <summary>
|
||||
/// If the source and destination are the same then this named texture can be used as
|
||||
/// the temporary copy location.
|
||||
/// If not set then a the pass will create its own temporary texture.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private string m_TempCopyNamedTemporaryName;
|
||||
|
||||
protected int m_TempCopyNamedTemporaryNameHash;
|
||||
|
||||
/// <summary>
|
||||
/// When to insert the pass
|
||||
/// </summary>
|
||||
[Header("What stage")]
|
||||
[SerializeField]
|
||||
protected RenderPassEvent m_WhenToInsert = RenderPassEvent.BeforeRenderingPostProcessing;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hashes of the named texture names.
|
||||
///
|
||||
/// NOTE: this should be called in the Create() of sub-classes.
|
||||
/// </summary>
|
||||
protected void DoCreate()
|
||||
{
|
||||
SetTextureNameHashes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if the source and destination are the same.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool IsSourceAndDestinationSame()
|
||||
{
|
||||
if (m_SourceTextureSourceType == TextureSourceType.CameraColour &&
|
||||
m_DestinationTextureSourceType == TextureSourceType.CameraColour)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_SourceTextureSourceType == TextureSourceType.NameTemporary &&
|
||||
m_DestinationTextureSourceType == TextureSourceType.NameTemporary)
|
||||
{
|
||||
//
|
||||
// Both using a named temporary texture, are they the same
|
||||
//
|
||||
return m_SourceNamedTemporaryNameHash == m_DestinationNamedTemporaryNameHash;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the texture name hashes from the current name values.
|
||||
/// </summary>
|
||||
protected void SetTextureNameHashes()
|
||||
{
|
||||
m_SourceNamedTemporaryNameHash =
|
||||
TemporaryCameraCopyTextureRenderFeature.GetNameHash(m_SourceNamedTemporaryName);
|
||||
m_DestinationNamedTemporaryNameHash =
|
||||
TemporaryCameraCopyTextureRenderFeature.GetNameHash(m_DestinationNamedTemporaryName);
|
||||
m_TempCopyNamedTemporaryNameHash =
|
||||
TemporaryCameraCopyTextureRenderFeature.GetNameHash(m_TempCopyNamedTemporaryName);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private bool m_EditorTextureHashesFoldout;
|
||||
protected virtual void EditorOnInspectorGUIAfterBase()
|
||||
{
|
||||
EditorGUILayout.LabelField("Info", EditorStyles.boldLabel);
|
||||
|
||||
var origIndent = EditorGUI.indentLevel;
|
||||
EditorGUI.indentLevel += 1;
|
||||
m_EditorTextureHashesFoldout = EditorGUILayout.Foldout(m_EditorTextureHashesFoldout, "Texture hashes");
|
||||
if (m_EditorTextureHashesFoldout)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorTextureNameAndHash("Source", m_SourceNamedTemporaryName, m_SourceNamedTemporaryNameHash);
|
||||
|
||||
EditorTextureNameAndHash("Destination", m_DestinationNamedTemporaryName,
|
||||
m_DestinationNamedTemporaryNameHash);
|
||||
|
||||
EditorTextureNameAndHash("Source", m_SourceNamedTemporaryName, m_SourceNamedTemporaryNameHash);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel = origIndent;
|
||||
|
||||
EditorGUILayout.LabelField("Controls", EditorStyles.boldLabel);
|
||||
|
||||
//
|
||||
// NOTE:
|
||||
// This button is not actually needed as the Create() of the render feature is called
|
||||
// if the exposed settings are changed.
|
||||
//
|
||||
if (GUILayout.Button("Update temp texture hashes"))
|
||||
{
|
||||
SetTextureNameHashes();
|
||||
}
|
||||
}
|
||||
|
||||
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(SourceToDestinationBlitRenderFeature), true)]
|
||||
private class SourceToDestinationBlitRenderFeatureEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
var me = target as SourceToDestinationBlitRenderFeature;
|
||||
if (me != null)
|
||||
{
|
||||
me.EditorOnInspectorGUIAfterBase();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The RenderPass for things that take a source, do some operation on it and put the
|
||||
/// result in some destination.
|
||||
///
|
||||
/// NOTE:
|
||||
/// If the source and destination are different then the execute must at least copy the
|
||||
/// source to the destination (as long as m_GoodToExecute is true) otherwise later
|
||||
/// passes may not see the correct texture contents.
|
||||
/// </summary>
|
||||
public abstract class SourceToDestinationBlitRenderPass : ScriptableRenderPass
|
||||
{
|
||||
/// <summary>
|
||||
/// If this pass needs to create a temporary texture (when the source and destination
|
||||
/// are the same) then is id is used.
|
||||
/// </summary>
|
||||
protected readonly int m_ScreenCopyID = Shader.PropertyToID("_ScreenCopy");
|
||||
|
||||
protected RenderFeatures.TextureSourceType m_SourceTextureSourceType;
|
||||
protected int m_SourceNamedTemporaryNameHash;
|
||||
|
||||
protected RenderFeatures.TextureSourceType m_DestinationTextureSourceType;
|
||||
protected int m_DestinationNamedTemporaryNameHash;
|
||||
|
||||
protected int m_SameSourceDestNamedTemporaryNameHash;
|
||||
|
||||
protected bool m_SourceAndDestinationSame;
|
||||
|
||||
/// <summary>
|
||||
/// If this is true then Execute() can happen, if false something went wrong in the pass setup
|
||||
/// so the Execute() should do nothing.
|
||||
/// </summary>
|
||||
protected bool m_GoodToExecute;
|
||||
|
||||
protected RenderTargetIdentifier m_CameraColourTargetIdentifier;
|
||||
protected RenderTargetIdentifier m_SourceTargetIdentifier;
|
||||
protected RenderTargetIdentifier m_DestinationTargetIdentifier;
|
||||
protected RenderTargetIdentifier m_TempCopyTargetIdentifier;
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the named textures and/or the camera colour texture and determines if the
|
||||
/// source and destination are the same.
|
||||
///
|
||||
/// NOTE:
|
||||
/// Call this from whatever setup type method the sub-class implements.
|
||||
/// </summary>
|
||||
protected void DoSetup(RenderPassEvent whenToRender, RenderTargetIdentifier cameraColourTargetIdentifier,
|
||||
RenderFeatures.TextureSourceType sourceSourceType, int tempSourceTextureHash,
|
||||
RenderFeatures.TextureSourceType destinationSourceType, int tempDestinationTextureHash,
|
||||
int sameSourceDestTextureHash)
|
||||
{
|
||||
renderPassEvent = whenToRender;
|
||||
m_CameraColourTargetIdentifier = cameraColourTargetIdentifier;
|
||||
|
||||
m_SourceTextureSourceType = sourceSourceType;
|
||||
m_SourceNamedTemporaryNameHash = tempSourceTextureHash;
|
||||
|
||||
m_DestinationTextureSourceType = destinationSourceType;
|
||||
m_DestinationNamedTemporaryNameHash = tempDestinationTextureHash;
|
||||
|
||||
m_SameSourceDestNamedTemporaryNameHash = sameSourceDestTextureHash;
|
||||
|
||||
m_SourceAndDestinationSame = false;
|
||||
|
||||
if (m_SourceTextureSourceType == TextureSourceType.CameraColour &&
|
||||
m_DestinationTextureSourceType == TextureSourceType.CameraColour)
|
||||
{
|
||||
m_SourceAndDestinationSame = true;
|
||||
}
|
||||
else if (m_SourceTextureSourceType == TextureSourceType.NameTemporary &&
|
||||
m_DestinationTextureSourceType == TextureSourceType.NameTemporary)
|
||||
{
|
||||
//
|
||||
// Both using a named temporary texture, are they the same
|
||||
//
|
||||
m_SourceAndDestinationSame = (m_SourceNamedTemporaryNameHash == m_DestinationNamedTemporaryNameHash);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the named textures and works out if all textures are available meaning that
|
||||
/// execution of the pass can go ahead.
|
||||
/// This create the local temporary copy texture if that is required.
|
||||
/// This sets up the RenderTargetIdentifiers the Execute() can then use.
|
||||
/// </summary>
|
||||
protected void DoOnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
m_GoodToExecute = false;
|
||||
if (m_SourceTextureSourceType == TextureSourceType.CameraColour)
|
||||
{
|
||||
m_SourceTargetIdentifier = m_CameraColourTargetIdentifier;
|
||||
}
|
||||
else if (!TemporaryCameraCopyTextureRenderFeature.TryGetTempTextureIdentifier(m_SourceNamedTemporaryNameHash, out m_SourceTargetIdentifier))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_DestinationTextureSourceType == TextureSourceType.CameraColour)
|
||||
{
|
||||
m_DestinationTargetIdentifier = m_CameraColourTargetIdentifier;
|
||||
}
|
||||
else if (!TemporaryCameraCopyTextureRenderFeature.TryGetTempTextureIdentifier(m_DestinationNamedTemporaryNameHash, out m_DestinationTargetIdentifier))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_SourceAndDestinationSame)
|
||||
{
|
||||
//
|
||||
// need some texture to use as a copy
|
||||
//
|
||||
if (m_SameSourceDestNamedTemporaryNameHash != TemporaryCameraCopyTextureRenderFeature.k_InvalidNameHash)
|
||||
{
|
||||
if (!TemporaryCameraCopyTextureRenderFeature.TryGetTempTextureIdentifier(m_SameSourceDestNamedTemporaryNameHash, out m_TempCopyTargetIdentifier))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Use our own temporary texture
|
||||
//
|
||||
#if ENABLE_VR
|
||||
var renderTextureDescriptor = XRSettings.enabled ? XRSettings.eyeTextureDesc : renderingData.cameraData.cameraTargetDescriptor;
|
||||
#else
|
||||
var renderTextureDescriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
#endif
|
||||
cmd.GetTemporaryRT(m_ScreenCopyID, renderTextureDescriptor);
|
||||
m_TempCopyTargetIdentifier = new RenderTargetIdentifier(m_ScreenCopyID);
|
||||
}
|
||||
}
|
||||
|
||||
m_GoodToExecute = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user