예제 #1
0
        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);
            }
        }
예제 #2
0
 public void EnaglePostProcessLayer( )
 {
     UnityEngine.Rendering.PostProcessing.PostProcessLayer postProcessLayer = GameObject.FindObjectOfType <UnityEngine.Rendering.PostProcessing.PostProcessLayer>();
     if (null != postProcessLayer)
     {
         postProcessLayer.enabled = true;
     }
 }
예제 #3
0
        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);
        }
예제 #4
0
        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
        }
예제 #5
0
 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);
                }
            }
        }
예제 #8
0
 /// <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());
 }
예제 #9
0
 /// <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);
 }
예제 #10
0
        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);
        }
예제 #11
0
        // 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);
                }
            }
        }