private void ConvertLayer(BIRPRendering.PostProcessLayer oldLayer, ref bool succeeded, StringBuilder errorString) { if (!succeeded) { return; } if (!oldLayer) { // TODO: unless there's good way to tell the if the object is just missing because it was already // converted as part of an earlier conversion object, then these two lines should be commented // out or removed. It should still return though. // succeeded = false; // errorString.AppendLine("PPv2 PostProcessLayer failed to be converted because the original asset reference was lost during conversion."); return; } if (PrefabUtility.IsPartOfPrefabInstance(oldLayer) && !PrefabUtility.IsAddedComponentOverride(oldLayer)) { // This is a property override on an instance of the component, // so override the component instance with the modifications. succeeded = ConvertLayerInstance(oldLayer, errorString); } else { // The entire component is unique, so just convert it succeeded = ConvertLayerComponent(oldLayer, errorString); } }
public void EnaglePostProcessLayer( ) { UnityEngine.Rendering.PostProcessing.PostProcessLayer postProcessLayer = GameObject.FindObjectOfType <UnityEngine.Rendering.PostProcessing.PostProcessLayer>(); if (null != postProcessLayer) { postProcessLayer.enabled = true; } }
private bool ConvertLayerComponent(BIRPRendering.PostProcessLayer oldLayer, StringBuilder errorString) { var siblingCamera = oldLayer.GetComponent <Camera>().GetUniversalAdditionalCameraData(); // PostProcessLayer requires a sibling Camera component, but // we check it here just in case something weird went happened. if (!siblingCamera) { errorString.AppendLine( "PPv2 PostProcessLayer failed to be converted because the instance object was missing a required sibling Camera component."); return(false); } // The presence of a PostProcessLayer implies the Camera should render post-processes siblingCamera.renderPostProcessing = true; siblingCamera.volumeLayerMask = oldLayer.volumeLayer; siblingCamera.volumeTrigger = oldLayer.volumeTrigger; siblingCamera.stopNaN = oldLayer.stopNaNPropagation; siblingCamera.antialiasingQuality = (URPRendering.AntialiasingQuality)oldLayer.subpixelMorphologicalAntialiasing.quality; switch (oldLayer.antialiasingMode) { case BIRPRendering.PostProcessLayer.Antialiasing.None: siblingCamera.antialiasing = URPRendering.AntialiasingMode.None; break; case BIRPRendering.PostProcessLayer.Antialiasing.FastApproximateAntialiasing: siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; break; case BIRPRendering.PostProcessLayer.Antialiasing.SubpixelMorphologicalAntialiasing: siblingCamera.antialiasing = URPRendering.AntialiasingMode.SubpixelMorphologicalAntiAliasing; break; default: // Default to the the most performant mode, since "None" is an explicit option. siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; break; } if (PrefabUtility.IsPartOfPrefabAsset(oldLayer)) { postConversionDestroyables.Add(oldLayer); } else { Object.DestroyImmediate(oldLayer, allowDestroyingAssets: true); } EditorUtility.SetDirty(siblingCamera.gameObject); return(true); }
public static void SetupCamera() { Camera cam = (Camera.main) ? Camera.main : GameObject.FindObjectOfType<Camera>(); GameObject mainCamera = cam.gameObject; if (!mainCamera) { Debug.LogError("<b>SC Post Effects</b> No camera found in scene to configure"); return; } #if URP UniversalAdditionalCameraData data = mainCamera.GetComponent<UniversalAdditionalCameraData>(); if (data) { data.renderPostProcessing = true; data.volumeTrigger = mainCamera.transform; EditorUtility.SetDirty(data); } #endif #if PPS //Avoid missing PostProcessing scripts //Add PostProcessLayer component if not already present if (mainCamera.GetComponent<UnityEngine.Rendering.PostProcessing.PostProcessLayer>() == false) { UnityEngine.Rendering.PostProcessing.PostProcessLayer ppLayer = mainCamera.AddComponent<UnityEngine.Rendering.PostProcessing.PostProcessLayer>(); ppLayer.volumeLayer = LayerMask.GetMask(LayerMask.LayerToName(SCPE.GetLayerID())); ppLayer.fog.enabled = false; Debug.Log("<b>PostProcessLayer</b> component was added to <b>" + mainCamera.name + "</b>"); cam.allowMSAA = false; cam.allowHDR = true; //Enable AA by default #if UNITY_2019_1_OR_NEWER ppLayer.antialiasingMode = UnityEngine.Rendering.PostProcessing.PostProcessLayer.Antialiasing.SubpixelMorphologicalAntialiasing; #else ppLayer.antialiasingMode = UnityEngine.Rendering.PostProcessing.PostProcessLayer.Antialiasing.FastApproximateAntialiasing; #endif Selection.objects = new[] { mainCamera }; EditorUtility.SetDirty(mainCamera); } #endif }
void Reset() { postProcessLayer = GetComponent <PostProcessLayer>(); }
internal void UpdateSettings(PostProcessLayer postProcessLayer) { // Reset to base state ReplaceData(postProcessLayer); // If no trigger is set, only global volumes will have influence var mask = postProcessLayer.volumeLayer.value; var volumeTrigger = postProcessLayer.volumeTrigger; var onlyGlobal = volumeTrigger == null; var triggerPos = onlyGlobal ? Vector3.zero : volumeTrigger.position; // Sort the cached volume list(s) for the given layer mask if needed and return it var volumes = GrabVolumes(mask); // Traverse all volumes foreach (var volume in volumes) { // Skip disabled volumes and volumes without any data or weight if (!volume.enabled || volume.profileRef == null || volume.weight <= 0f) { continue; } var settings = volume.profileRef.settings; // Global volume always have influence if (volume.isGlobal) { postProcessLayer.OverrideSettings(settings, Mathf.Clamp01(volume.weight)); continue; } if (onlyGlobal) { continue; } // If volume isn't global and has no collider, skip it as it's useless var colliders = m_TempColliders; volume.GetComponents(colliders); if (colliders.Count == 0) { continue; } // Find closest distance to volume, 0 means it's inside it var closestDistanceSqr = float.PositiveInfinity; foreach (var collider in colliders) { if (!collider.enabled) { continue; } var closestPoint = collider.ClosestPoint(triggerPos); // 5.6-only API var d = ((closestPoint - triggerPos) / 2f).sqrMagnitude; if (d < closestDistanceSqr) { closestDistanceSqr = d; } } colliders.Clear(); var blendDistSqr = volume.blendDistance * volume.blendDistance; // Volume has no influence, ignore it // Note: Volume doesn't do anything when `closestDistanceSqr = blendDistSqr` but // we can't use a >= comparison as blendDistSqr could be set to 0 in which // case volume would have total influence if (closestDistanceSqr > blendDistSqr) { continue; } // Volume has influence var interpFactor = 1f; if (blendDistSqr > 0f) { interpFactor = 1f - closestDistanceSqr / blendDistSqr; } // No need to clamp01 the interpolation factor as it'll always be in [0;1[ range postProcessLayer.OverrideSettings(settings, interpFactor * Mathf.Clamp01(volume.weight)); } }
// Gets a list of all volumes currently affecting the given layer. Results aren't sorted. // Volume with weight of 0 or no profile set will be skipped. Results list won't be cleared. public void GetActiveVolumes(PostProcessLayer layer, List <PostProcessVolume> results, bool skipDisabled = true, bool skipZeroWeight = true) { // If no trigger is set, only global volumes will have influence var mask = layer.volumeLayer.value; var volumeTrigger = layer.volumeTrigger; var onlyGlobal = volumeTrigger == null; var triggerPos = onlyGlobal ? Vector3.zero : volumeTrigger.position; // Sort the cached volume list(s) for the given layer mask if needed and return it var volumes = GrabVolumes(mask); // Traverse all volumes foreach (var volume in volumes) { // Skip disabled volumes and volumes without any data or weight if (skipDisabled && !volume.enabled || volume.profileRef == null || skipZeroWeight && volume.weight <= 0f) { continue; } // Global volume always have influence if (volume.isGlobal) { results.Add(volume); continue; } if (onlyGlobal) { continue; } // If volume isn't global and has no collider, skip it as it's useless var colliders = m_TempColliders; volume.GetComponents(colliders); if (colliders.Count == 0) { continue; } // Find closest distance to volume, 0 means it's inside it var closestDistanceSqr = float.PositiveInfinity; foreach (var collider in colliders) { if (!collider.enabled) { continue; } var closestPoint = collider.ClosestPoint(triggerPos); // 5.6-only API var d = ((closestPoint - triggerPos) / 2f).sqrMagnitude; if (d < closestDistanceSqr) { closestDistanceSqr = d; } } colliders.Clear(); var blendDistSqr = volume.blendDistance * volume.blendDistance; // Check for influence if (closestDistanceSqr <= blendDistSqr) { results.Add(volume); } } }
/// <summary> /// Checks if temporal anti-aliasing is active on a given post-process layer. /// </summary> /// <param name="layer">The layer to check</param> /// <returns><c>true</c> if temporal anti-aliasing is active, <c>false</c> otherwise</returns> public static bool IsTemporalAntialiasingActive(PostProcessLayer layer) { return(IsPostProcessingActive(layer) && layer.antialiasingMode == PostProcessLayer.Antialiasing.TemporalAntialiasing && layer.temporalAntialiasing.IsSupported()); }
/// <summary> /// Checks if a post-processing layer is active. /// </summary> /// <param name="layer">The layer to check; can be <c>null</c></param> /// <returns><c>true</c> if the layer is enabled, <c>false</c> otherwise</returns> public static bool IsPostProcessingActive(PostProcessLayer layer) { return(layer != null && layer.enabled); }
private bool ConvertLayerInstance(BIRPRendering.PostProcessLayer oldLayer, StringBuilder errorString) { // First get a reference to the local instance of the camera (which is required by PostProcessingLayer) var siblingCamera = oldLayer.GetComponent <Camera>().GetUniversalAdditionalCameraData(); if (!siblingCamera) { errorString.AppendLine( "PPv2 PostProcessLayer failed to be converted because the instance object was missing a required sibling Camera component."); return(false); } var oldModifications = PrefabUtility.GetPropertyModifications(oldLayer); foreach (var oldModification in oldModifications) { if (oldModification.target is BIRPRendering.PostProcessLayer) { if (oldModification.propertyPath.EndsWith("volumeLayer", StringComparison.InvariantCultureIgnoreCase)) { siblingCamera.volumeLayerMask = oldLayer.volumeLayer; } else if (oldModification.propertyPath.EndsWith("volumeTrigger", StringComparison.InvariantCultureIgnoreCase)) { siblingCamera.volumeTrigger = oldLayer.volumeTrigger; } else if (oldModification.propertyPath.EndsWith("stopNaNPropagation", StringComparison.InvariantCultureIgnoreCase)) { siblingCamera.stopNaN = oldLayer.stopNaNPropagation; } else if (oldModification.propertyPath.EndsWith("quality", StringComparison.InvariantCultureIgnoreCase)) { siblingCamera.antialiasingQuality = (URPRendering.AntialiasingQuality)oldLayer.subpixelMorphologicalAntialiasing.quality; } else if (oldModification.propertyPath.EndsWith("antialiasingMode", StringComparison.InvariantCultureIgnoreCase)) { switch (oldLayer.antialiasingMode) { case BIRPRendering.PostProcessLayer.Antialiasing.None: siblingCamera.antialiasing = URPRendering.AntialiasingMode.None; break; case BIRPRendering.PostProcessLayer.Antialiasing.FastApproximateAntialiasing: siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; break; case BIRPRendering.PostProcessLayer.Antialiasing.SubpixelMorphologicalAntialiasing: siblingCamera.antialiasing = URPRendering.AntialiasingMode.SubpixelMorphologicalAntiAliasing; break; default: // Default to the the most performant mode, since "None" is an explicit option. siblingCamera.antialiasing = URPRendering.AntialiasingMode.FastApproximateAntialiasing; break; } } EditorUtility.SetDirty(siblingCamera); } } return(true); }
// Gets a list of all volumes currently affecting the given layer. Results aren't sorted. // Volume with weight of 0 or no profile set will be skipped. Results list won't be cleared. public void GetActiveVolumes(PostProcessLayer layer, List <PostProcessVolume> results) { // If no trigger is set, only global volumes will have influence int mask = layer.volumeLayer.value; var volumeTrigger = layer.volumeTrigger; bool onlyGlobal = volumeTrigger == null; var triggerPos = onlyGlobal ? Vector3.zero : volumeTrigger.position; for (int i = 0; i < k_MaxLayerCount; i++) { // Skip layers not in the mask if ((mask & (1 << i)) == 0) { continue; } // Skip empty layers var volumes = m_Volumes[i]; if (volumes == null) { continue; } // Traverse all volumes foreach (var volume in volumes) { // Skip disabled volumes and volumes without any data or weight if (!volume.enabled || volume.profileRef == null || volume.weight <= 0f) { continue; } // Global volume always have influence if (volume.isGlobal) { results.Add(volume); continue; } if (onlyGlobal) { continue; } // If volume isn't global and has no collider, skip it as it's useless var colliders = m_TempColliders; volume.GetComponents(colliders); if (colliders.Count == 0) { continue; } // Find closest distance to volume, 0 means it's inside it float closestDistanceSqr = float.PositiveInfinity; foreach (var collider in colliders) { if (!collider.enabled) { continue; } var closestPoint = collider.ClosestPoint(triggerPos); // 5.6-only API var d = ((closestPoint - triggerPos) / 2f).sqrMagnitude; if (d < closestDistanceSqr) { closestDistanceSqr = d; } } colliders.Clear(); float blendDistSqr = volume.blendDistance * volume.blendDistance; // Check for influence if (closestDistanceSqr <= blendDistSqr) { results.Add(volume); } } } }
internal void UpdateSettings(PostProcessLayer postProcessLayer) { // Reset to base state postProcessLayer.OverrideSettings(m_BaseSettings, 1f); // If no trigger is set, only global volumes will have influence int mask = postProcessLayer.volumeLayer.value; var volumeTrigger = postProcessLayer.volumeTrigger; bool onlyGlobal = volumeTrigger == null; var triggerPos = onlyGlobal ? Vector3.zero : volumeTrigger.position; for (int i = 0; i < k_MaxLayerCount; i++) { // Skip layers not in the mask if ((mask & (1 << i)) == 0) { continue; } // Skip empty layers var volumes = m_Volumes[i]; if (volumes == null) { continue; } // Sort the volume list if needed if (m_SortNeeded[i]) { SortByPriority(volumes); m_SortNeeded[i] = false; } // Traverse all volumes foreach (var volume in volumes) { // Skip disabled volumes and volumes without any data or weight if (!volume.enabled || volume.profileRef == null || volume.weight <= 0f) { continue; } var settings = volume.profileRef.settings; // Global volume always have influence if (volume.isGlobal) { postProcessLayer.OverrideSettings(settings, volume.weight); continue; } if (onlyGlobal) { continue; } // If volume isn't global and has no collider, skip it as it's useless var colliders = m_TempColliders; volume.GetComponents(colliders); if (colliders.Count == 0) { continue; } // Find closest distance to volume, 0 means it's inside it float closestDistanceSqr = float.PositiveInfinity; foreach (var collider in colliders) { if (!collider.enabled) { continue; } var closestPoint = collider.ClosestPoint(triggerPos); // 5.6-only API var d = ((closestPoint - triggerPos) / 2f).sqrMagnitude; if (d < closestDistanceSqr) { closestDistanceSqr = d; } } colliders.Clear(); float blendDistSqr = volume.blendDistance * volume.blendDistance; // Volume has no influence, ignore it // Note: Volume doesn't do anything when `closestDistanceSqr = blendDistSqr` but // we can't use a >= comparison as blendDistSqr could be set to 0 in which // case volume would have total influence if (closestDistanceSqr > blendDistSqr) { continue; } // Volume has influence float interpFactor = 1f; if (blendDistSqr > 0f) { interpFactor = 1f - (closestDistanceSqr / blendDistSqr); } // No need to clamp01 the interpolation factor as it'll always be in [0;1[ range postProcessLayer.OverrideSettings(settings, interpFactor * volume.weight); } } }