A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR
2using UnityEditor;
3#endif
4
5using System;
6using System.Dynamic;
7using UnityEngine.Serialization;
8
9namespace UnityEngine.Rendering
10{
11 /// <summary>
12 /// Data-Driven Lens Flare can be added on any gameobject
13 /// </summary>
14 [ExecuteAlways]
15 [AddComponentMenu("Rendering/Lens Flare (SRP)")]
16 public sealed class LensFlareComponentSRP : MonoBehaviour
17 {
18 [SerializeField]
19 private LensFlareDataSRP m_LensFlareData = null;
20
21 enum Version
22 {
23 Initial,
24 }
25
26 #pragma warning disable 414
27 [SerializeField]
28 Version version = Version.Initial;
29 #pragma warning restore 414
30
31 /// <summary>
32 /// Lens flare asset used on this component
33 /// </summary>
34 public LensFlareDataSRP lensFlareData
35 {
36 get
37 {
38 return m_LensFlareData;
39 }
40 set
41 {
42 m_LensFlareData = value;
43 OnValidate();
44 }
45 }
46
47 /// <summary>
48 /// Intensity
49 /// </summary>
50 [Min(0.0f)]
51 public float intensity = 1.0f;
52 /// <summary>
53 /// Distance used to scale the Distance Attenuation Curve
54 /// </summary>
55 [Min(1e-5f)]
56 public float maxAttenuationDistance = 100.0f;
57 /// <summary>
58 /// Distance used to scale the Scale Attenuation Curve
59 /// </summary>
60 [Min(1e-5f)]
61 public float maxAttenuationScale = 100.0f;
62 /// <summary>
63 /// Attenuation by distance
64 /// </summary>
65 public AnimationCurve distanceAttenuationCurve = new AnimationCurve(new Keyframe(0.0f, 1.0f), new Keyframe(1.0f, 0.0f));
66 /// <summary>
67 /// Scale by distance, use the same distance as distanceAttenuationCurve
68 /// </summary>
69 public AnimationCurve scaleByDistanceCurve = new AnimationCurve(new Keyframe(0.0f, 1.0f), new Keyframe(1.0f, 0.0f));
70 /// <summary>
71 /// If component attached to a light, attenuation the lens flare per light type
72 /// </summary>
73 public bool attenuationByLightShape = true;
74 /// <summary>
75 /// Attenuation used radially, which allow for instance to enable flare only on the edge of the screen
76 /// </summary>
77 public AnimationCurve radialScreenAttenuationCurve = new AnimationCurve(new Keyframe(0.0f, 1.0f), new Keyframe(1.0f, 1.0f));
78
79 /// <summary>
80 /// Enable Occlusion feature
81 /// </summary>
82 public bool useOcclusion = false;
83 /// <summary>
84 /// Enable Occlusion using Background Cloud (for instance: CloudLayer)
85 /// Please use useFogOpacityOcclusion instead.
86 /// </summary>
87 [Obsolete("Replaced by environmentOcclusion.")]
88 public bool useBackgroundCloudOcclusion = false;
89
90 /// <summary>Enable occlusion from environment effects supported by the render pipeline. This may include opacity from volumetric clouds, background clouds, fog and water.</summary>
91 [FormerlySerializedAs("volumetricCloudOcclusion")]
92 [FormerlySerializedAs("useFogOpacityOcclusion")]
93 public bool environmentOcclusion = false;
94 /// <summary>
95 /// Enable Occlusion with Water
96 /// </summary>
97 [Obsolete("Replaced by environmentOcclusion.")]
98 public bool useWaterOcclusion = false;
99 /// <summary>
100 /// Radius around the light used to occlude the flare (value in world space)
101 /// </summary>
102 [Min(0.0f)]
103 public float occlusionRadius = 0.1f;
104 /// <summary>
105 /// Random Samples Count used inside the disk with 'occlusionRadius'
106 /// </summary>
107 [Range(1, 64)]
108 public uint sampleCount = 32;
109 /// <summary>
110 /// Z Occlusion Offset allow us to offset the plane where the disc of occlusion is place (closer to camera), value on world space.
111 /// Useful for instance to sample occlusion outside a light bulb if we place a flare inside the light bulb
112 /// </summary>
113 public float occlusionOffset = 0.05f;
114 /// <summary>
115 /// Global Scale
116 /// </summary>
117 [Min(0.0f)]
118 public float scale = 1.0f;
119 /// <summary>
120 /// If allowOffScreen is true then If the lens flare is outside the screen we still emit the flare on screen
121 /// </summary>
122 public bool allowOffScreen = false;
123 /// <summary>
124 /// If volumetricCloudOcclusion is true then use the volumetric cloud (on HDRP only) for the occlusion
125 /// Please use useFogOpacityOcclusion instead.
126 /// </summary>
127 [Obsolete("Please use environmentOcclusion instead.")]
128 public bool volumetricCloudOcclusion = false;
129
130 /// Our default celestial body will have an angular radius of 3.3 degrees. This is an arbitrary number, but must be kept constant
131 /// so the occlusion radius for direct lights is consistent regardless of near / far clip plane configuration.
132 private static float sCelestialAngularRadius = 3.3f * Mathf.PI / 180.0f;
133
134 /// <summary>
135 /// OcclusionRemapCurve allow the occlusion [from 0 to 1] to be remap with any desired shape.
136 /// </summary>
137 public TextureCurve occlusionRemapCurve = new TextureCurve(AnimationCurve.Linear(0.0f, 0.0f, 1.0f, 1.0f), 1.0f, false, new Vector2(0.0f, 1.0f));
138
139 /// <summary>
140 /// Light override, change the light which influences the flares including "modulate by light color" and "Attenuation By Light Shape" but not the position.
141 /// </summary>
142 public Light lightOverride = null;
143
144 /// <summary>
145 /// Retrieves the projected occlusion radius from a particular celestial in the infinity plane with an angular radius.
146 /// This is used for directional lights which require to have consistent occlusion radius regardless of the near/farplane configuration.
147 /// </summary>
148 /// <param name="mainCam">The camera utilized to calculate the occlusion radius</param>
149 /// <returns>The value, in world units, of the occlusion angular radius.</returns>
150 public float celestialProjectedOcclusionRadius(Camera mainCam)
151 {
152 float projectedRadius = (float)Math.Tan(sCelestialAngularRadius) * mainCam.farClipPlane;
153 return occlusionRadius * projectedRadius;
154 }
155
156 void Awake()
157 {
158#if UNITY_EDITOR
159 if (!lensFlareData)
160 lensFlareData = AssetDatabase.LoadAssetAtPath<LensFlareDataSRP>("Packages/com.unity.render-pipelines.core/Runtime/RenderPipelineResources/Default Lens Flare (SRP).asset");
161#endif
162 }
163
164 /// <summary>
165 /// Add or remove the lens flare to the queue of PostProcess
166 /// </summary>
167 void OnEnable()
168 {
169 if (lensFlareData)
170 LensFlareCommonSRP.Instance.AddData(this);
171 else
172 LensFlareCommonSRP.Instance.RemoveData(this);
173 }
174
175 /// <summary>
176 /// Remove the lens flare from the queue of PostProcess
177 /// </summary>
178 void OnDisable()
179 {
180 LensFlareCommonSRP.Instance.RemoveData(this);
181 }
182
183 /// <summary>
184 /// Add or remove the lens flare from the queue of PostProcess
185 /// </summary>
186 void OnValidate()
187 {
188 if (isActiveAndEnabled && lensFlareData != null)
189 {
190 LensFlareCommonSRP.Instance.AddData(this);
191 }
192 else
193 {
194 LensFlareCommonSRP.Instance.RemoveData(this);
195 }
196 }
197
198 private void OnDestroy()
199 {
200 occlusionRemapCurve.Release();
201 }
202
203#if UNITY_EDITOR
204 private float sDebugClippingSafePercentage = 0.9f; //for debug gizmo, only push 90% further so we avoid clipping of debug lines.
205 void OnDrawGizmosSelected()
206 {
207 Camera mainCam = Camera.current;
208 if (mainCam != null && useOcclusion)
209 {
210 Vector3 positionWS;
211 float adjustedOcclusionRadius = occlusionRadius;
212 Light light = GetComponent<Light>();
213 if (light != null && light.type == LightType.Directional)
214 {
215 positionWS = -transform.forward * (mainCam.farClipPlane * sDebugClippingSafePercentage) + mainCam.transform.position;
216 adjustedOcclusionRadius = celestialProjectedOcclusionRadius(mainCam);
217 }
218 else
219 {
220 positionWS = transform.position;
221 }
222
223 Color previousH = Handles.color;
224 Color previousG = Gizmos.color;
225 Handles.color = Color.red;
226 Gizmos.color = Color.red;
227 Vector3 dir = (mainCam.transform.position - positionWS).normalized;
228 Handles.DrawWireDisc(positionWS + dir * occlusionOffset, dir, adjustedOcclusionRadius, 1.0f);
229 Gizmos.DrawWireSphere(positionWS, occlusionOffset);
230 Gizmos.color = previousG;
231 Handles.color = previousH;
232 }
233 }
234#endif
235 }
236}