using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
namespace Sources.CustomRenderer.Features
{
public class MotionVectorRenderPass : ScriptableRenderPass
{
const string kObjectShader = "Hidden/CustomRenderer/VelocityObjects";
private static readonly int m_velocityTexId = Shader.PropertyToID("_VelocityTexture");
private List<ShaderTagId> s_ShaderTags;
Material m_ObjectMaterial;
MotionData m_MotionData;
private RenderTargetIdentifier m_velocityTextureTarget = new RenderTargetIdentifier(m_velocityTexId, 0, CubemapFace.Unknown, -1);
private RenderTextureDescriptor m_velocityTextureDescriptor;
public MotionVectorRenderPass()
{
// Set data
renderPassEvent = RenderPassEvent.AfterRenderingGbuffer;
}
public void Setup(MotionData motionData)
{
if (s_ShaderTags == null)
{
s_ShaderTags = new List<ShaderTagId>()
{
new ShaderTagId("LightweightForward"),
new ShaderTagId("SRPDefaultUnlit"), new ShaderTagId("UniversalForward"), new ShaderTagId("UniversalForwardOnly"),
new ShaderTagId("Unlit"), new ShaderTagId("ForwardLit")
};
}
m_MotionData = motionData;
m_ObjectMaterial = new Material(Shader.Find(kObjectShader));
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
RenderTextureDescriptor cameraTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor;
RenderTextureDescriptor descriptor = cameraTargetDescriptor;
descriptor.depthBufferBits = 32;
m_velocityTextureDescriptor = descriptor;
m_velocityTextureDescriptor.graphicsFormat = GraphicsFormat.R16G16B16A16_SFloat;
cmd.GetTemporaryRT(m_velocityTexId, m_velocityTextureDescriptor, FilterMode.Point);
ConfigureTarget(m_velocityTextureTarget);
ConfigureClear(ClearFlag.All, Color.black);
}
public override void OnCameraCleanup(CommandBuffer cmd)
{
if (cmd == null)
throw new ArgumentNullException("cmd");
cmd.ReleaseTemporaryRT(m_velocityTexId);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
var camera = renderingData.cameraData.camera;
CommandBuffer cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, new ProfilingSampler("VelocityVector")))
{
camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
var drawingSettings = GetDrawingSettings(ref renderingData);
var filteringSettings = new FilteringSettings(RenderQueueRange.all, camera.cullingMask);
var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
//var cullingResults = context.Cull(ref cullingParameters);
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filteringSettings, ref renderStateBlock);
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
DrawingSettings GetDrawingSettings(ref RenderingData renderingData)
{
// Drawing Settings
var camera = renderingData.cameraData.camera;
var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque };
var drawingSettings = new DrawingSettings(ShaderTagId.none, sortingSettings)
{
perObjectData = PerObjectData.MotionVectors,
enableDynamicBatching = renderingData.supportsDynamicBatching,
enableInstancing = true,
};
// Shader Tags
for (int i = 0; i < s_ShaderTags.Count; ++i)
{
drawingSettings.SetShaderPassName(i, s_ShaderTags[i]);
}
// Material
drawingSettings.overrideMaterial = m_ObjectMaterial;
drawingSettings.overrideMaterialPassIndex = 0;
return drawingSettings;
}
}
}