Files
2025-05-18 22:39:39 +03:00

168 lines
6.5 KiB
C#

using Golems.RenderFeatures;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.XR;
using static Golems.ScriptableRenderPassHelper;
namespace Golems
{
public class AlbertGhostMemoryCompositePass : SourceToDestinationBlitRenderPass
{
private const string k_Shader = "Hidden/AlbertGhostMemoryComposite";
private const string k_ProfilerIdent = "CompositePass";
private AlbertGhostMemoryCompositeSettings m_Settings;
private bool m_SettingsSet = false;
private Material m_CompositeMat = null;
private float m_Time = 0.0f;
private bool m_IsEnabled;
#region Shader Properties
private readonly int RandomValueID = Shader.PropertyToID("RandomValue");
private readonly int TimeLapseID = Shader.PropertyToID("TimeLapse");
private readonly int EdgeValueID = Shader.PropertyToID("EdgeValue");
private readonly int GlobalAlphaID = Shader.PropertyToID("GlobalAlpha");
private readonly int OffsetRedXID = Shader.PropertyToID("OffsetRedX");
private readonly int OffsetGreenXID = Shader.PropertyToID("OffsetGreenX");
private readonly int OffsetBlueXID = Shader.PropertyToID("OffsetBlueX");
private readonly int OffsetRedYID = Shader.PropertyToID("OffsetRedY");
private readonly int OffsetGreenYID = Shader.PropertyToID("OffsetGreenY");
private readonly int OffsetBlueYID = Shader.PropertyToID("OffsetBlueY");
private readonly int BrightnessID = Shader.PropertyToID("Brightness");
private readonly int ContrastID = Shader.PropertyToID("Contrast");
#endregion
public AlbertGhostMemoryCompositePass(AlbertGhostMemoryCompositeSettings settings)
{
SetSettings(settings);
CreateMaterial(k_Shader, out m_CompositeMat);
m_Time = 0.0f;
}
public void SetSettings(AlbertGhostMemoryCompositeSettings settings)
{
m_Settings = settings;
m_SettingsSet = m_Settings != null;
}
public bool HasSettings()
{
return m_SettingsSet;
}
public void Setup(bool isEnabled, RenderPassEvent whenToRender, RenderTargetIdentifier cameraColourTargetIdentifier,
RenderFeatures.TextureSourceType sourceSourceType, int tempSourceTextureHash,
RenderFeatures.TextureSourceType destinationSourceType, int tempDestinationTextureHash,
int sameSourceDestTextureHash)
{
m_IsEnabled = isEnabled;
DoSetup(whenToRender, cameraColourTargetIdentifier,
sourceSourceType, tempSourceTextureHash,
destinationSourceType, tempDestinationTextureHash,
sameSourceDestTextureHash);
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
DoOnCameraSetup(cmd, ref renderingData);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (!m_GoodToExecute)
{
return;
}
//
// If we do not have settings yet we at least need to do a copy so later
// stages have something to work with.
//
var forceCopy = !m_SettingsSet;
#if UNITY_EDITOR
//
// In Editor at edit time the material will get destroyed on scene load
//
if (m_CompositeMat == null)
{
CreateMaterial(k_Shader, out m_CompositeMat);
}
#endif
bool doCopyOnly = forceCopy || !m_IsEnabled || GhostObjectCollection.Instance.NumberOfObjectsRendered <= 0;
if (doCopyOnly)
{
//
// nothing to render
//
if (!m_SourceAndDestinationSame)
{
//
// Copy the source to the destination
//
var copyCmd = CommandBufferPool.Get(k_ProfilerIdent);
copyCmd.Blit(m_SourceTargetIdentifier, m_DestinationTargetIdentifier);
context.ExecuteCommandBuffer(copyCmd);
CommandBufferPool.Release(copyCmd);
}
return;
}
SetAllShaderParameters();
CommandBuffer cmd = CommandBufferPool.Get(k_ProfilerIdent);
Compose(cmd);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
/// <summary>
/// Setup all the required values for
/// the composition shader pass
/// </summary>
private void SetAllShaderParameters ()
{
m_Time += Time.deltaTime;
float random = Random.Range(0.0f, 1.0f);
m_CompositeMat.SetFloat(RandomValueID, random);
m_CompositeMat.SetFloat(TimeLapseID, m_Time);
m_CompositeMat.SetFloat(EdgeValueID, m_Settings.EdgeValue);
m_CompositeMat.SetFloat(GlobalAlphaID, m_Settings.Alpha);
float ca_sin = m_Settings.ChromaticAberration * Mathf.Sin(m_Time * m_Settings.ChromaticAberrationSpeed);
float ca_cos = m_Settings.ChromaticAberration * Mathf.Cos(m_Time * m_Settings.ChromaticAberrationSpeed);
float ca_combo = (ca_sin + ca_cos);
m_CompositeMat.SetFloat(OffsetRedXID, ca_sin);
m_CompositeMat.SetFloat(OffsetGreenXID, ca_combo);
m_CompositeMat.SetFloat(OffsetBlueXID, ca_cos);
m_CompositeMat.SetFloat(OffsetRedYID, ca_sin);
m_CompositeMat.SetFloat(OffsetGreenYID, ca_combo);
m_CompositeMat.SetFloat(OffsetBlueYID, -ca_cos);
m_CompositeMat.SetFloat(BrightnessID, m_Settings.Brightness);
m_CompositeMat.SetFloat(ContrastID, m_Settings.Contrast);
}
/// <summary>
/// Compose the results of AlbertGhostMemoryPass into the cameraColorTarget
/// </summary>
private void Compose(in CommandBuffer cmd)
{
if (m_SourceAndDestinationSame)
{
cmd.Blit(m_SourceTargetIdentifier, m_TempCopyTargetIdentifier, m_CompositeMat);
cmd.Blit(m_TempCopyTargetIdentifier, m_DestinationTargetIdentifier);
}
else
{
cmd.Blit(m_SourceTargetIdentifier, m_DestinationTargetIdentifier, m_CompositeMat);
}
}
}
}