//using UnityEngine.Rendering; //namespace UnityEngine.PostProcessing //{ // using Settings = MotionBlurModel.Settings; // public sealed class MotionBlurComponent : PostProcessingComponentCommandBuffer // { // static class Uniforms // { // internal static readonly int _VelocityScale = Shader.PropertyToID("_VelocityScale"); // internal static readonly int _MaxBlurRadius = Shader.PropertyToID("_MaxBlurRadius"); // internal static readonly int _VelocityTex = Shader.PropertyToID("_VelocityTex"); // internal static readonly int _Tile4RT = Shader.PropertyToID("_Tile4RT"); // internal static readonly int _MainTex = Shader.PropertyToID("_MainTex"); // internal static readonly int _Tile8RT = Shader.PropertyToID("_Tile8RT"); // internal static readonly int _TileMaxOffs = Shader.PropertyToID("_TileMaxOffs"); // internal static readonly int _TileMaxLoop = Shader.PropertyToID("_TileMaxLoop"); // internal static readonly int _TileVRT = Shader.PropertyToID("_TileVRT"); // internal static readonly int _NeighborMaxTex = Shader.PropertyToID("_NeighborMaxTex"); // internal static readonly int _LoopCount = Shader.PropertyToID("_LoopCount"); // internal static readonly int _TempRT = Shader.PropertyToID("_TempRT"); // internal static readonly int _History1LumaTex = Shader.PropertyToID("_History1LumaTex"); // internal static readonly int _History2LumaTex = Shader.PropertyToID("_History2LumaTex"); // internal static readonly int _History3LumaTex = Shader.PropertyToID("_History3LumaTex"); // internal static readonly int _History4LumaTex = Shader.PropertyToID("_History4LumaTex"); // internal static readonly int _History1ChromaTex = Shader.PropertyToID("_History1ChromaTex"); // internal static readonly int _History2ChromaTex = Shader.PropertyToID("_History2ChromaTex"); // internal static readonly int _History3ChromaTex = Shader.PropertyToID("_History3ChromaTex"); // internal static readonly int _History4ChromaTex = Shader.PropertyToID("_History4ChromaTex"); // internal static readonly int _History1Weight = Shader.PropertyToID("_History1Weight"); // internal static readonly int _History2Weight = Shader.PropertyToID("_History2Weight"); // internal static readonly int _History3Weight = Shader.PropertyToID("_History3Weight"); // internal static readonly int _History4Weight = Shader.PropertyToID("_History4Weight"); // } // enum Pass // { // VelocitySetup, // TileMax4, // TileMax2, // TileMaxV, // NeighborMax, // Reconstruction, // ReconstructionUnroll, // FrameCompression, // FrameBlendingChroma, // FrameBlendingRaw // } // public class ReconstructionFilter // { // // Texture format for storing 2D vectors. // RenderTextureFormat m_VectorRTFormat = RenderTextureFormat.RGHalf; // // Texture format for storing packed velocity/depth. // RenderTextureFormat m_PackedRTFormat = RenderTextureFormat.ARGB2101010; // bool m_UseUnrolledShader; // public ReconstructionFilter() // { // CheckTextureFormatSupport(); // // Use loop unrolling on Adreno GPUs to avoid shader issues. // m_UseUnrolledShader = SystemInfo.graphicsDeviceName.Contains("Adreno"); // } // void CheckTextureFormatSupport() // { // // If 2:10:10:10 isn't supported, use ARGB32 instead. // if (!SystemInfo.SupportsRenderTextureFormat(m_PackedRTFormat)) // m_PackedRTFormat = RenderTextureFormat.ARGB32; // } // public bool IsSupported() // { // return SystemInfo.supportsMotionVectors; // } // public void ProcessImage(PostProcessingContext context, CommandBuffer cb, ref Settings settings, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material) // { // const float kMaxBlurRadius = 5f; // // Calculate the maximum blur radius in pixels. // int maxBlurPixels = (int)(kMaxBlurRadius * context.height / 100); // // Calculate the TileMax size. // // It should be a multiple of 8 and larger than maxBlur. // int tileSize = ((maxBlurPixels - 1) / 8 + 1) * 8; // // Pass 1 - Velocity/depth packing // // Motion vectors are scaled by an empirical factor of 1.45. // var velocityScale = settings.shutterAngle / 360f * 1.45f; // cb.SetGlobalFloat(Uniforms._VelocityScale, velocityScale); // cb.SetGlobalFloat(Uniforms._MaxBlurRadius, maxBlurPixels); // int vbuffer = Uniforms._VelocityTex; // cb.GetTemporaryRT(vbuffer, context.width, context.height, 0, FilterMode.Point, m_PackedRTFormat); // cb.Blit((Texture)null, vbuffer, material, (int)Pass.VelocitySetup); // // Pass 2 - First TileMax filter (1/4 downsize) // int tile4 = Uniforms._Tile4RT; // cb.GetTemporaryRT(tile4, context.width / 4, context.height / 4, 0, FilterMode.Point, m_VectorRTFormat); // cb.SetGlobalTexture(Uniforms._MainTex, vbuffer); // cb.Blit(vbuffer, tile4, material, (int)Pass.TileMax4); // // Pass 3 - Second TileMax filter (1/2 downsize) // int tile8 = Uniforms._Tile8RT; // cb.GetTemporaryRT(tile8, context.width / 8, context.height / 8, 0, FilterMode.Point, m_VectorRTFormat); // cb.SetGlobalTexture(Uniforms._MainTex, tile4); // cb.Blit(tile4, tile8, material, (int)Pass.TileMax2); // cb.ReleaseTemporaryRT(tile4); // // Pass 4 - Third TileMax filter (reduce to tileSize) // var tileMaxOffs = Vector2.one * (tileSize / 8f - 1f) * -0.5f; // cb.SetGlobalVector(Uniforms._TileMaxOffs, tileMaxOffs); // cb.SetGlobalFloat(Uniforms._TileMaxLoop, (int)(tileSize / 8f)); // int tile = Uniforms._TileVRT; // cb.GetTemporaryRT(tile, context.width / tileSize, context.height / tileSize, 0, FilterMode.Point, m_VectorRTFormat); // cb.SetGlobalTexture(Uniforms._MainTex, tile8); // cb.Blit(tile8, tile, material, (int)Pass.TileMaxV); // cb.ReleaseTemporaryRT(tile8); // // Pass 5 - NeighborMax filter // int neighborMax = Uniforms._NeighborMaxTex; // int neighborMaxWidth = context.width / tileSize; // int neighborMaxHeight = context.height / tileSize; // cb.GetTemporaryRT(neighborMax, neighborMaxWidth, neighborMaxHeight, 0, FilterMode.Point, m_VectorRTFormat); // cb.SetGlobalTexture(Uniforms._MainTex, tile); // cb.Blit(tile, neighborMax, material, (int)Pass.NeighborMax); // cb.ReleaseTemporaryRT(tile); // // Pass 6 - Reconstruction pass // cb.SetGlobalFloat(Uniforms._LoopCount, Mathf.Clamp(settings.sampleCount / 2, 1, 64)); // cb.SetGlobalFloat(Uniforms._MaxBlurRadius, maxBlurPixels); // cb.SetGlobalTexture(Uniforms._MainTex, source); // cb.Blit(source, destination, material, m_UseUnrolledShader ? (int)Pass.ReconstructionUnroll : (int)Pass.Reconstruction); // cb.ReleaseTemporaryRT(vbuffer); // cb.ReleaseTemporaryRT(neighborMax); // } // } // public class FrameBlendingFilter // { // struct Frame // { // public RenderTexture lumaTexture; // public RenderTexture chromaTexture; // float m_Time; // RenderTargetIdentifier[] m_MRT; // public float CalculateWeight(float strength, float currentTime) // { // if (Mathf.Approximately(m_Time, 0f)) // return 0f; // var coeff = Mathf.Lerp(80f, 16f, strength); // return Mathf.Exp((m_Time - currentTime) * coeff); // } // public void Release() // { // if (lumaTexture != null) // RenderTexture.ReleaseTemporary(lumaTexture); // if (chromaTexture != null) // RenderTexture.ReleaseTemporary(chromaTexture); // lumaTexture = null; // chromaTexture = null; // } // public void MakeRecord(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, Material material) // { // Release(); // lumaTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.R8); // chromaTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.R8); // lumaTexture.filterMode = FilterMode.Point; // chromaTexture.filterMode = FilterMode.Point; // if (m_MRT == null) // m_MRT = new RenderTargetIdentifier[2]; // m_MRT[0] = lumaTexture; // m_MRT[1] = chromaTexture; // cb.SetGlobalTexture(Uniforms._MainTex, source); // cb.SetRenderTarget(m_MRT, lumaTexture); // cb.DrawMesh(GraphicsUtils.quad, Matrix4x4.identity, material, 0, (int)Pass.FrameCompression); // m_Time = Time.time; // } // public void MakeRecordRaw(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, RenderTextureFormat format) // { // Release(); // lumaTexture = RenderTexture.GetTemporary(width, height, 0, format); // lumaTexture.filterMode = FilterMode.Point; // cb.SetGlobalTexture(Uniforms._MainTex, source); // cb.Blit(source, lumaTexture); // m_Time = Time.time; // } // } // bool m_UseCompression; // RenderTextureFormat m_RawTextureFormat; // Frame[] m_FrameList; // int m_LastFrameCount; // public FrameBlendingFilter() // { // m_UseCompression = CheckSupportCompression(); // m_RawTextureFormat = GetPreferredRenderTextureFormat(); // m_FrameList = new Frame[4]; // } // public void Dispose() // { // foreach (var frame in m_FrameList) // frame.Release(); // } // public void PushFrame(CommandBuffer cb, RenderTargetIdentifier source, int width, int height, Material material) // { // // Push only when actual update (do nothing while pausing) // var frameCount = Time.frameCount; // if (frameCount == m_LastFrameCount) return; // // Update the frame record. // var index = frameCount % m_FrameList.Length; // if (m_UseCompression) // m_FrameList[index].MakeRecord(cb, source, width, height, material); // else // m_FrameList[index].MakeRecordRaw(cb, source, width, height, m_RawTextureFormat); // m_LastFrameCount = frameCount; // } // public void BlendFrames(CommandBuffer cb, float strength, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material) // { // var t = Time.time; // var f1 = GetFrameRelative(-1); // var f2 = GetFrameRelative(-2); // var f3 = GetFrameRelative(-3); // var f4 = GetFrameRelative(-4); // cb.SetGlobalTexture(Uniforms._History1LumaTex, f1.lumaTexture); // cb.SetGlobalTexture(Uniforms._History2LumaTex, f2.lumaTexture); // cb.SetGlobalTexture(Uniforms._History3LumaTex, f3.lumaTexture); // cb.SetGlobalTexture(Uniforms._History4LumaTex, f4.lumaTexture); // cb.SetGlobalTexture(Uniforms._History1ChromaTex, f1.chromaTexture); // cb.SetGlobalTexture(Uniforms._History2ChromaTex, f2.chromaTexture); // cb.SetGlobalTexture(Uniforms._History3ChromaTex, f3.chromaTexture); // cb.SetGlobalTexture(Uniforms._History4ChromaTex, f4.chromaTexture); // cb.SetGlobalFloat(Uniforms._History1Weight, f1.CalculateWeight(strength, t)); // cb.SetGlobalFloat(Uniforms._History2Weight, f2.CalculateWeight(strength, t)); // cb.SetGlobalFloat(Uniforms._History3Weight, f3.CalculateWeight(strength, t)); // cb.SetGlobalFloat(Uniforms._History4Weight, f4.CalculateWeight(strength, t)); // cb.SetGlobalTexture(Uniforms._MainTex, source); // cb.Blit(source, destination, material, m_UseCompression ? (int)Pass.FrameBlendingChroma : (int)Pass.FrameBlendingRaw); // } // // Check if the platform has the capability of compression. // static bool CheckSupportCompression() // { // return // SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8) && // SystemInfo.supportedRenderTargetCount > 1; // } // // Determine which 16-bit render texture format is available. // static RenderTextureFormat GetPreferredRenderTextureFormat() // { // RenderTextureFormat[] formats = // { // RenderTextureFormat.RGB565, // RenderTextureFormat.ARGB1555, // RenderTextureFormat.ARGB4444 // }; // foreach (var f in formats) // if (SystemInfo.SupportsRenderTextureFormat(f)) return f; // return RenderTextureFormat.Default; // } // // Retrieve a frame record with relative indexing. // // Use a negative index to refer to previous frames. // Frame GetFrameRelative(int offset) // { // var index = (Time.frameCount + m_FrameList.Length + offset) % m_FrameList.Length; // return m_FrameList[index]; // } // } // ReconstructionFilter m_ReconstructionFilter; // public ReconstructionFilter reconstructionFilter // { // get // { // if (m_ReconstructionFilter == null) // m_ReconstructionFilter = new ReconstructionFilter(); // return m_ReconstructionFilter; // } // } // FrameBlendingFilter m_FrameBlendingFilter; // public FrameBlendingFilter frameBlendingFilter // { // get // { // if (m_FrameBlendingFilter == null) // m_FrameBlendingFilter = new FrameBlendingFilter(); // return m_FrameBlendingFilter; // } // } // bool m_FirstFrame = true; // public override bool active // { // get // { // var settings = model.settings; // return model.enabled // && ((settings.shutterAngle > 0f && reconstructionFilter.IsSupported()) || settings.frameBlending > 0f) // && SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2 // No movecs on GLES2 platforms // && !context.interrupted; // } // } // public override string GetName() // { // return "Motion Blur"; // } // public void ResetHistory() // { // if (m_FrameBlendingFilter != null) // m_FrameBlendingFilter.Dispose(); // m_FrameBlendingFilter = null; // } // public override DepthTextureMode GetCameraFlags() // { // return DepthTextureMode.Depth | DepthTextureMode.MotionVectors; // } // public override CameraEvent GetCameraEvent() // { // return CameraEvent.BeforeImageEffects; // } // public override void OnEnable() // { // m_FirstFrame = true; // } // public override void PopulateCommandBuffer(CommandBuffer cb) // { //#if UNITY_EDITOR // // Don't render motion blur preview when the editor is not playing as it can in some // // cases results in ugly artifacts (i.e. when resizing the game view). // if (!Application.isPlaying) // return; //#endif // // Skip rendering in the first frame as motion vectors won't be abvailable until the // // next one // if (m_FirstFrame) // { // m_FirstFrame = false; // return; // } // var material = context.materialFactory.Get("Hidden/Post FX/Motion Blur"); // var blitMaterial = context.materialFactory.Get("Hidden/Post FX/Blit"); // var settings = model.settings; // var fbFormat = context.isHdr // ? RenderTextureFormat.DefaultHDR // : RenderTextureFormat.Default; // int tempRT = Uniforms._TempRT; // cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Point, fbFormat); // if (settings.shutterAngle > 0f && settings.frameBlending > 0f) // { // // Motion blur + frame blending // reconstructionFilter.ProcessImage(context, cb, ref settings, BuiltinRenderTextureType.CameraTarget, tempRT, material); // frameBlendingFilter.BlendFrames(cb, settings.frameBlending, tempRT, BuiltinRenderTextureType.CameraTarget, material); // frameBlendingFilter.PushFrame(cb, tempRT, context.width, context.height, material); // } // else if (settings.shutterAngle > 0f) // { // // No frame blending // cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget); // cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, blitMaterial, 0); // reconstructionFilter.ProcessImage(context, cb, ref settings, tempRT, BuiltinRenderTextureType.CameraTarget, material); // } // else if (settings.frameBlending > 0f) // { // // Frame blending only // cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget); // cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, blitMaterial, 0); // frameBlendingFilter.BlendFrames(cb, settings.frameBlending, tempRT, BuiltinRenderTextureType.CameraTarget, material); // frameBlendingFilter.PushFrame(cb, tempRT, context.width, context.height, material); // } // // Cleaning up // cb.ReleaseTemporaryRT(tempRT); // } // public override void OnDisable() // { // if (m_FrameBlendingFilter != null) // m_FrameBlendingFilter.Dispose(); // } // } //}