/// <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 <CustomPostProcessRenderer> InstantiateRenderers(List <String> names, Dictionary <string, CustomPostProcessRenderer> shared) { var renderers = new List <CustomPostProcessRenderer>(names.Count); foreach (var name in names) { if (shared.TryGetValue(name, out var renderer)) { renderers.Add(renderer); } else { var type = Type.GetType(name); if (type == null || !type.IsSubclassOf(typeof(CustomPostProcessRenderer))) { continue; } var attribute = CustomPostProcessAttribute.GetAttribute(type); if (attribute == null) { continue; } renderer = Activator.CreateInstance(type) as CustomPostProcessRenderer; renderers.Add(renderer); if (attribute.ShareInstance) { shared.Add(name, renderer); } } } return(renderers); }
/// <summary> /// Construct the custom post-processing render pass /// </summary> /// <param name="injectionPoint">The post processing injection point</param> /// <param name="classes">The list of classes for the renderers to be executed by this render pass</param> public CustomPostProcessRenderPass(CustomPostProcessInjectionPoint injectionPoint, List <CustomPostProcessRenderer> renderers) { this.injectionPoint = injectionPoint; this.m_ProfilingSamplers = new List <ProfilingSampler>(renderers.Count); this.m_PostProcessRenderers = renderers; foreach (var renderer in renderers) { // Get renderer name and add it to the names list var attribute = CustomPostProcessAttribute.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 CustomPostProcessInjectionPoint.AfterOpaqueAndSky: renderPassEvent = RenderPassEvent.AfterRenderingSkybox; m_PassName = "Custom PostProcess after Opaque & Sky"; break; case CustomPostProcessInjectionPoint.BeforePostProcess: renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; m_PassName = "Custom PostProcess before PostProcess"; break; case CustomPostProcessInjectionPoint.AfterPostProcess: // NOTE: This was initially "AfterRenderingPostProcessing" but it made the builtin post-processing to blit directly to the camera target. renderPassEvent = RenderPassEvent.AfterRendering; m_PassName = "Custom 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> /// Finds all the custom post-processing renderer classes and categorizes them by injection point /// </summary> private void populateRenderers() { if (_availableRenderers != null) { return; } _availableRenderers = new Dictionary <CustomPostProcessInjectionPoint, List <Type> >() { { CustomPostProcessInjectionPoint.AfterOpaqueAndSky, new List <Type>() }, { CustomPostProcessInjectionPoint.BeforePostProcess, new List <Type>() }, { CustomPostProcessInjectionPoint.AfterPostProcess, new List <Type>() } }; foreach (var type in TypeCache.GetTypesDerivedFrom <CustomPostProcessRenderer>()) { if (type.IsAbstract) { continue; } var attributes = type.GetCustomAttributes(typeof(CustomPostProcessAttribute), false); if (attributes.Length != 1) { continue; } CustomPostProcessAttribute attribute = attributes[0] as CustomPostProcessAttribute; if (attribute.InjectionPoint.HasFlag(CustomPostProcessInjectionPoint.AfterOpaqueAndSky)) { _availableRenderers[CustomPostProcessInjectionPoint.AfterOpaqueAndSky].Add(type); } if (attribute.InjectionPoint.HasFlag(CustomPostProcessInjectionPoint.BeforePostProcess)) { _availableRenderers[CustomPostProcessInjectionPoint.BeforePostProcess].Add(type); } if (attribute.InjectionPoint.HasFlag(CustomPostProcessInjectionPoint.AfterPostProcess)) { _availableRenderers[CustomPostProcessInjectionPoint.AfterPostProcess].Add(type); } } }
/// <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(CustomPostProcessAttribute.GetAttribute(type)?.Name ?? type?.Name); }