From 643803eba88338f5cc5c423dd5a09b7d0206a1d8 Mon Sep 17 00:00:00 2001 From: Kleber Garcia Date: Mon, 13 Sep 2021 16:55:42 -0400 Subject: [PATCH 1/2] Making occlusion radius consistent for directional lights, regardless of near/far plane distance. --- .../PostProcessing/LensFlareCommonSRP.cs | 4 ++- .../PostProcessing/LensFlareComponentSRP.cs | 25 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs b/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs index 5f464cf7621..da489d36d09 100644 --- a/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs +++ b/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs @@ -422,8 +422,10 @@ static public void DoLensFlareDataDrivenCommon(Material lensFlareShader, LensFla Vector3 dir = (cam.transform.position - comp.transform.position).normalized; Vector3 screenPosZ = WorldToViewport(isCameraRelative, viewProjMatrix, cam.transform.position, positionWS + dir * comp.occlusionOffset); + + float adjustedOcclusionRadius = isDirLight ? comp.celestialProjectedOcclusionRadius(cam) : comp.occlusionRadius; Vector2 occlusionRadiusEdgeScreenPos0 = (Vector2)viewportPos; - Vector2 occlusionRadiusEdgeScreenPos1 = (Vector2)WorldToViewport(isCameraRelative, viewProjMatrix, cam.transform.position, positionWS + cam.transform.up * comp.occlusionRadius); + Vector2 occlusionRadiusEdgeScreenPos1 = (Vector2)WorldToViewport(isCameraRelative, viewProjMatrix, cam.transform.position, positionWS + cam.transform.up * adjustedOcclusionRadius); float occlusionRadius = (occlusionRadiusEdgeScreenPos1 - occlusionRadiusEdgeScreenPos0).magnitude; cmd.SetGlobalVector(_FlareData1, new Vector4(occlusionRadius, comp.sampleCount, screenPosZ.z, actualHeight / actualWidth)); diff --git a/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs b/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs index 4e7468e9924..49f2cc2f3cd 100644 --- a/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs +++ b/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareComponentSRP.cs @@ -2,6 +2,8 @@ using UnityEditor; #endif +using System; + namespace UnityEngine.Rendering { /// @@ -90,6 +92,22 @@ public LensFlareDataSRP lensFlareData /// public bool allowOffScreen = false; + /// Our default celestial body will have an angular radius of 3.3 degrees. This is an arbitrary number, but must be kept constant + /// so the occlusion radius for direct lights is consistent regardless of near / far clip plane configuration. + private static float sCelestialAngularRadius = 3.3f * Mathf.PI / 180.0f; + + /// + /// Retrieves the projected occlusion radius from a particular celestial in the infinity plane with an angular radius. + /// This is used for directional lights which require to have consistent occlusion radius regardless of the near/farplane configuration. + /// The camera utilized to calculate the occlusion radius + /// The value, in world units, of the occlusion angular radius. + /// + public float celestialProjectedOcclusionRadius(Camera mainCam) + { + float projectedRadius = (float)Math.Tan(sCelestialAngularRadius) * mainCam.farClipPlane; + return occlusionRadius * projectedRadius; + } + /// /// Add or remove the lens flare to the queue of PostProcess /// @@ -125,16 +143,19 @@ void OnValidate() } #if UNITY_EDITOR + private float sDebugClippingSafePercentage = 0.9f; //for debug gizmo, only push 90% further so we avoid clipping of debug lines. void OnDrawGizmosSelected() { Camera mainCam = Camera.current; if (mainCam != null && useOcclusion) { Vector3 positionWS; + float adjustedOcclusionRadius = occlusionRadius; Light light = GetComponent(); if (light != null && light.type == LightType.Directional) { - positionWS = -transform.forward * mainCam.farClipPlane + mainCam.transform.position; + positionWS = -transform.forward * (mainCam.farClipPlane * sDebugClippingSafePercentage) + mainCam.transform.position; + adjustedOcclusionRadius = celestialProjectedOcclusionRadius(mainCam); } else { @@ -146,7 +167,7 @@ void OnDrawGizmosSelected() Handles.color = Color.red; Gizmos.color = Color.red; Vector3 dir = (mainCam.transform.position - positionWS).normalized; - Handles.DrawWireDisc(positionWS + dir * occlusionOffset, dir, occlusionRadius, 1.0f); + Handles.DrawWireDisc(positionWS + dir * occlusionOffset, dir, adjustedOcclusionRadius, 1.0f); Gizmos.DrawWireSphere(positionWS, occlusionOffset); Gizmos.color = previousG; Handles.color = previousH; From bd7027de6c2f14d55e7e6c21259df5e9780a9eee Mon Sep 17 00:00:00 2001 From: Kleber Garcia Date: Mon, 13 Sep 2021 17:05:39 -0400 Subject: [PATCH 2/2] Changelog --- com.unity.render-pipelines.core/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.render-pipelines.core/CHANGELOG.md b/com.unity.render-pipelines.core/CHANGELOG.md index d128a3bb6f6..3341124fb74 100644 --- a/com.unity.render-pipelines.core/CHANGELOG.md +++ b/com.unity.render-pipelines.core/CHANGELOG.md @@ -108,6 +108,7 @@ The version number for this package has increased due to a version update of a r - Improved IntegrateLDCharlie() to use uniform stratified sampling for faster convergence towards the ground truth - DynamicResolutionHandler.GetScaledSize function now clamps, and never allows to return a size greater than its input. - Removed DYNAMIC_RESOLUTION snippet on lens flare common shader. Its not necessary any more on HDRP, which simplifies the shader. +- Made occlusion Radius for lens flares in directional lights, be independant of the camera's far plane. ## [11.0.0] - 2020-10-21