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
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;