/// <summary> /// Construct the custom post-processing render pass /// </summary> /// <param name="injectionPoint">The post processing injection point</param> /// <param name="renderers">The list of classes for the renderers to be executed by this render pass</param> public CompoundPass(InjectionPoint injectionPoint, List <CompoundRenderer> renderers) { _injectionPoint = injectionPoint; m_ProfilingSamplers = new List <ProfilingSampler>(renderers.Count); m_PostProcessRenderers = renderers; foreach (var renderer in renderers) { // Get renderer name and add it to the names list var attribute = CompoundRendererFeatureAttribute.GetAttribute(renderer.GetType()); m_ProfilingSamplers.Add(new ProfilingSampler(attribute?.Name)); } // Pre-allocate a list for active renderers this.m_ActivePostProcessRenderers = new List <int>(renderers.Count); // Set render pass event and name based on the injection point. switch (injectionPoint) { case InjectionPoint.AfterOpaqueAndSky: renderPassEvent = RenderPassEvent.AfterRenderingSkybox; m_PassName = "[Dustyroom] PostProcess after Opaque & Sky"; break; case InjectionPoint.BeforePostProcess: renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; m_PassName = "[Dustyroom] PostProcess before PostProcess"; break; case InjectionPoint.AfterPostProcess: #if UNITY_2021_2_OR_NEWER renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing; #else // NOTE: This was initially "AfterRenderingPostProcessing" but it made the builtin post-processing // to blit directly to the camera target. renderPassEvent = RenderPassEvent.AfterRendering; #endif m_PassName = "[Dustyroom] PostProcess after PostProcess"; break; } // Initialize the IDs and allocation state of the intermediate render targets m_Intermediate = new RenderTargetHandle[2]; m_Intermediate[0].Init("_IntermediateRT0"); m_Intermediate[1].Init("_IntermediateRT1"); m_IntermediateAllocated = new bool[2]; m_IntermediateAllocated[0] = false; m_IntermediateAllocated[1] = false; }
/// <summary> /// Converts the class name (AssemblyQualifiedName) to an instance. Filters out types that /// don't exist or don't match the requirements. /// </summary> /// <param name="names">The list of assembly-qualified class names</param> /// <param name="shared">Dictionary of shared instances keyed by class name</param> /// <returns>List of renderers</returns> private List <CompoundRenderer> InstantiateRenderers(List <String> names, Dictionary <string, CompoundRenderer> shared) { var renderers = new List <CompoundRenderer>(names.Count); foreach (var n in names) { if (shared.TryGetValue(n, out var renderer)) { renderers.Add(renderer); } else { var type = Type.GetType(n); if (type == null || !type.IsSubclassOf(typeof(CompoundRenderer))) { continue; } var attribute = CompoundRendererFeatureAttribute.GetAttribute(type); if (attribute == null) { continue; } renderer = Activator.CreateInstance(type) as CompoundRenderer; renderers.Add(renderer); if (attribute.ShareInstance) { shared.Add(n, renderer); } } } return(renderers); }
/// <summary> /// Get the renderer name from the attached custom post-process attribute. /// </summary> /// <param name="type"></param> /// <returns></returns> private string GetName(Type type) { return(CompoundRendererFeatureAttribute.GetAttribute(type)?.Name ?? type?.Name); }