LensSettings.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. using UnityEngine;
  2. using System;
  3. #if CINEMACHINE_HDRP || CINEMACHINE_URP
  4. #if CINEMACHINE_HDRP_7_3_1
  5. using UnityEngine.Rendering.HighDefinition;
  6. #else
  7. #if CINEMACHINE_URP
  8. using UnityEngine.Rendering.Universal;
  9. #else
  10. using UnityEngine.Experimental.Rendering.HDPipeline;
  11. #endif
  12. #endif
  13. #endif
  14. namespace Cinemachine
  15. {
  16. /// <summary>
  17. /// Describes the FOV and clip planes for a camera. This generally mirrors the Unity Camera's
  18. /// lens settings, and will be used to drive the Unity camera when the vcam is active.
  19. /// </summary>
  20. [Serializable]
  21. [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)]
  22. public struct LensSettings
  23. {
  24. /// <summary>Default Lens Settings</summary>
  25. public static LensSettings Default = new LensSettings(40f, 10f, 0.1f, 5000f, 0);
  26. /// <summary>
  27. /// This is the camera view in degrees. For cinematic people, a 50mm lens
  28. /// on a super-35mm sensor would equal a 19.6 degree FOV
  29. /// </summary>
  30. [Range(1f, 179f)]
  31. [Tooltip("This is the camera view in degrees. Display will be in vertical degress, unless the "
  32. + "associated camera has its FOV axis setting set to Horizontal, in which case display will "
  33. + "be in horizontal degress. Internally, it is always vertical degrees. "
  34. + "For cinematic people, a 50mm lens on a super-35mm sensor would equal a 19.6 degree FOV")]
  35. public float FieldOfView;
  36. /// <summary>
  37. /// When using an orthographic camera, this defines the half-height, in world
  38. /// co-ordinates, of the camera view.
  39. /// </summary>
  40. [Tooltip("When using an orthographic camera, this defines the half-height, in world "
  41. + "coordinates, of the camera view.")]
  42. public float OrthographicSize;
  43. /// <summary>
  44. /// The near clip plane for this LensSettings
  45. /// </summary>
  46. [Tooltip("This defines the near region in the renderable range of the camera frustum. "
  47. + "Raising this value will stop the game from drawing things near the camera, which "
  48. + "can sometimes come in handy. Larger values will also increase your shadow resolution.")]
  49. public float NearClipPlane;
  50. /// <summary>
  51. /// The far clip plane for this LensSettings
  52. /// </summary>
  53. [Tooltip("This defines the far region of the renderable range of the camera frustum. Typically "
  54. + "you want to set this value as low as possible without cutting off desired distant objects")]
  55. public float FarClipPlane;
  56. /// <summary>
  57. /// The dutch (tilt) to be applied to the camera. In degrees
  58. /// </summary>
  59. [Range(-180f, 180f)]
  60. [Tooltip("Camera Z roll, or tilt, in degrees.")]
  61. public float Dutch;
  62. /// <summary>
  63. /// This enum controls how the Camera seetings are driven. Some settings
  64. /// can be pulled from the main camera, or pushed to it, depending on these values.
  65. /// </summary>
  66. public enum OverrideModes
  67. {
  68. /// <summary> Perspective/Ortho, IsPhysical
  69. /// will not be changed in Unity Camera. This is the default setting.</summary>
  70. None = 0,
  71. /// <summary>Orthographic projection mode will be pushed to the Unity Camera</summary>
  72. Orthographic,
  73. /// <summary>Perspective projection mode will be pushed to the Unity Camera</summary>
  74. Perspective,
  75. /// <summary>A physically-modeled Perspective projection type will be pushed
  76. /// to the Unity Camera</summary>
  77. Physical
  78. }
  79. /// <summary>
  80. /// Allows you to select a different camera mode to apply to the Camera component
  81. /// when Cinemachine activates this Virtual Camera. The changes applied to the Camera
  82. /// component through this setting will remain after the Virtual Camera deactivation.
  83. /// </summary>
  84. [Tooltip("Allows you to select a different camera mode to apply to the Camera component "
  85. + "when Cinemachine activates this Virtual Camera. The changes applied to the Camera "
  86. + "component through this setting will remain after the Virtual Camera deactivation.")]
  87. public OverrideModes ModeOverride;
  88. /// <summary>
  89. /// This is set every frame by the virtual camera, based on the value found in the
  90. /// currently associated Unity camera.
  91. /// Do not set this property. Instead, use the ModeOverride field to set orthographic mode.
  92. /// </summary>
  93. public bool Orthographic
  94. {
  95. get => ModeOverride == OverrideModes.Orthographic || ModeOverride == OverrideModes.None && m_OrthoFromCamera;
  96. /// Obsolete: do not use
  97. set { m_OrthoFromCamera = value; ModeOverride = value
  98. ? OverrideModes.Orthographic : OverrideModes.Perspective; }
  99. }
  100. /// <summary>
  101. /// For physical cameras, this is the actual size of the image sensor (in mm); it is used to
  102. /// convert between focal length and field of vue. For nonphysical cameras, it is the aspect ratio.
  103. /// </summary>
  104. public Vector2 SensorSize
  105. {
  106. get { return m_SensorSize; }
  107. set { m_SensorSize = value; }
  108. }
  109. /// <summary>
  110. /// Sensor aspect, not screen aspect. For nonphysical cameras, this is the same thing.
  111. /// </summary>
  112. public float Aspect { get { return SensorSize.y == 0 ? 1f : (SensorSize.x / SensorSize.y); } }
  113. /// <summary>
  114. /// This property will be true if the camera mode is set, either directly or
  115. /// indirectly, to Physical Camera
  116. /// Do not set this property. Instead, use the ModeOverride field to set physical mode.
  117. /// </summary>
  118. public bool IsPhysicalCamera
  119. {
  120. get { return ModeOverride == OverrideModes.Physical
  121. || ModeOverride == OverrideModes.None && m_PhysicalFromCamera; }
  122. /// Obsolete: do not use
  123. set { m_PhysicalFromCamera = value; ModeOverride = value
  124. ? OverrideModes.Physical : OverrideModes.Perspective; }
  125. }
  126. /// <summary>For physical cameras only: position of the gate relative to
  127. /// the film back</summary>
  128. public Vector2 LensShift;
  129. /// <summary>For physical cameras only: how the image is fitted to the sensor
  130. /// if the aspect ratios differ</summary>
  131. public Camera.GateFitMode GateFit;
  132. #if UNITY_2022_2_OR_NEWER
  133. /// <summary>For physical cameras only: how far from the camera to the point
  134. /// of sharpest focus</summary>
  135. public float FocusDistance;
  136. #endif
  137. [SerializeField]
  138. Vector2 m_SensorSize;
  139. bool m_OrthoFromCamera;
  140. bool m_PhysicalFromCamera;
  141. #if CINEMACHINE_HDRP
  142. public int Iso;
  143. public float ShutterSpeed;
  144. #if CINEMACHINE_HDRP_14
  145. [Range(Camera.kMinAperture, Camera.kMaxAperture)]
  146. public float Aperture;
  147. [Range(Camera.kMinBladeCount, Camera.kMaxBladeCount)]
  148. #else
  149. [Range(HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture)]
  150. public float Aperture;
  151. [Range(HDPhysicalCamera.kMinBladeCount, HDPhysicalCamera.kMaxBladeCount)]
  152. #endif
  153. public int BladeCount;
  154. public Vector2 Curvature;
  155. [Range(0, 1)]
  156. public float BarrelClipping;
  157. [Range(-1, 1)]
  158. public float Anamorphism;
  159. #endif
  160. /// <summary>
  161. /// Creates a new LensSettings, copying the values from the
  162. /// supplied Camera
  163. /// </summary>
  164. /// <param name="fromCamera">The Camera from which the FoV, near
  165. /// and far clip planes will be copied.</param>
  166. /// <returns>The LensSettings as extracted from the supplied Camera</returns>
  167. public static LensSettings FromCamera(Camera fromCamera)
  168. {
  169. LensSettings lens = Default;
  170. if (fromCamera != null)
  171. {
  172. lens.FieldOfView = fromCamera.fieldOfView;
  173. lens.OrthographicSize = fromCamera.orthographicSize;
  174. lens.NearClipPlane = fromCamera.nearClipPlane;
  175. lens.FarClipPlane = fromCamera.farClipPlane;
  176. lens.LensShift = fromCamera.lensShift;
  177. lens.GateFit = fromCamera.gateFit;
  178. #if UNITY_2022_2_OR_NEWER
  179. lens.FocusDistance = fromCamera.focusDistance;
  180. #endif
  181. lens.SnapshotCameraReadOnlyProperties(fromCamera);
  182. #if CINEMACHINE_HDRP
  183. if (lens.IsPhysicalCamera)
  184. {
  185. #if CINEMACHINE_HDRP_14
  186. lens.Iso = fromCamera.iso;
  187. lens.ShutterSpeed = fromCamera.shutterSpeed;
  188. lens.Aperture = fromCamera.aperture;
  189. lens.BladeCount = fromCamera.bladeCount;
  190. lens.Curvature = fromCamera.curvature;
  191. lens.BarrelClipping = fromCamera.barrelClipping;
  192. lens.Anamorphism = fromCamera.anamorphism;
  193. #else
  194. var pc = new HDPhysicalCamera();
  195. #if UNITY_2019_2_OR_NEWER
  196. fromCamera.TryGetComponent<HDAdditionalCameraData>(out var hda);
  197. #else
  198. var hda = fromCamera.GetComponent<HDAdditionalCameraData>();
  199. #endif
  200. if (hda != null)
  201. pc = hda.physicalParameters;
  202. lens.Iso = pc.iso;
  203. lens.ShutterSpeed = pc.shutterSpeed;
  204. lens.Aperture = pc.aperture;
  205. lens.BladeCount = pc.bladeCount;
  206. lens.Curvature = pc.curvature;
  207. lens.BarrelClipping = pc.barrelClipping;
  208. lens.Anamorphism = pc.anamorphism;
  209. #endif
  210. }
  211. #endif
  212. }
  213. return lens;
  214. }
  215. /// <summary>
  216. /// Snapshot the properties that are read-only in the Camera
  217. /// </summary>
  218. /// <param name="camera">The Camera from which we will take the info</param>
  219. public void SnapshotCameraReadOnlyProperties(Camera camera)
  220. {
  221. m_OrthoFromCamera = false;
  222. m_PhysicalFromCamera = false;
  223. if (camera != null && ModeOverride == OverrideModes.None)
  224. {
  225. m_OrthoFromCamera = camera.orthographic;
  226. m_PhysicalFromCamera = camera.usePhysicalProperties;
  227. m_SensorSize = camera.sensorSize;
  228. GateFit = camera.gateFit;
  229. }
  230. if (IsPhysicalCamera)
  231. {
  232. // If uninitialized, do an initial pull from the camera
  233. if (camera != null && m_SensorSize == Vector2.zero)
  234. {
  235. m_SensorSize = camera.sensorSize;
  236. GateFit = camera.gateFit;
  237. }
  238. }
  239. else
  240. {
  241. if (camera != null)
  242. m_SensorSize = new Vector2(camera.aspect, 1f);
  243. LensShift = Vector2.zero;
  244. }
  245. }
  246. /// <summary>
  247. /// Snapshot the properties that are read-only in the Camera
  248. /// </summary>
  249. /// <param name="lens">The LensSettings from which we will take the info</param>
  250. public void SnapshotCameraReadOnlyProperties(ref LensSettings lens)
  251. {
  252. if (ModeOverride == OverrideModes.None)
  253. {
  254. m_OrthoFromCamera = lens.Orthographic;
  255. m_SensorSize = lens.m_SensorSize;
  256. m_PhysicalFromCamera = lens.IsPhysicalCamera;
  257. }
  258. if (!IsPhysicalCamera)
  259. LensShift = Vector2.zero;
  260. }
  261. /// <summary>
  262. /// Explicit constructor for this LensSettings
  263. /// </summary>
  264. /// <param name="verticalFOV">The Vertical field of view</param>
  265. /// <param name="orthographicSize">If orthographic, this is the half-height of the screen</param>
  266. /// <param name="nearClip">The near clip plane</param>
  267. /// <param name="farClip">The far clip plane</param>
  268. /// <param name="dutch">Camera roll, in degrees. This is applied at the end
  269. /// after shot composition.</param>
  270. public LensSettings(
  271. float verticalFOV, float orthographicSize,
  272. float nearClip, float farClip, float dutch) : this()
  273. {
  274. FieldOfView = verticalFOV;
  275. OrthographicSize = orthographicSize;
  276. NearClipPlane = nearClip;
  277. FarClipPlane = farClip;
  278. Dutch = dutch;
  279. m_SensorSize = new Vector2(1, 1);
  280. GateFit = Camera.GateFitMode.Horizontal;
  281. #if UNITY_2022_2_OR_NEWER
  282. FocusDistance = 10;
  283. #endif
  284. #if CINEMACHINE_HDRP
  285. Iso = 200;
  286. ShutterSpeed = 0.005f;
  287. Aperture = 16;
  288. BladeCount = 5;
  289. Curvature = new Vector2(2, 11);
  290. BarrelClipping = 0.25f;
  291. Anamorphism = 0;
  292. #endif
  293. }
  294. /// <summary>
  295. /// Linearly blends the fields of two LensSettings and returns the result
  296. /// </summary>
  297. /// <param name="lensA">The LensSettings to blend from</param>
  298. /// <param name="lensB">The LensSettings to blend to</param>
  299. /// <param name="t">The interpolation value. Internally clamped to the range [0,1]</param>
  300. /// <returns>Interpolated settings</returns>
  301. public static LensSettings Lerp(LensSettings lensA, LensSettings lensB, float t)
  302. {
  303. t = Mathf.Clamp01(t);
  304. LensSettings blendedLens = t < 0.5f ? lensA : lensB; // non-lerpable settings taken care of here
  305. blendedLens.FarClipPlane = Mathf.Lerp(lensA.FarClipPlane, lensB.FarClipPlane, t);
  306. blendedLens.NearClipPlane = Mathf.Lerp(lensA.NearClipPlane, lensB.NearClipPlane, t);
  307. blendedLens.FieldOfView = Mathf.Lerp(lensA.FieldOfView, lensB.FieldOfView, t);
  308. blendedLens.OrthographicSize = Mathf.Lerp(lensA.OrthographicSize, lensB.OrthographicSize, t);
  309. blendedLens.Dutch = Mathf.Lerp(lensA.Dutch, lensB.Dutch, t);
  310. blendedLens.m_SensorSize = Vector2.Lerp(lensA.m_SensorSize, lensB.m_SensorSize, t);
  311. blendedLens.LensShift = Vector2.Lerp(lensA.LensShift, lensB.LensShift, t);
  312. #if UNITY_2022_2_OR_NEWER
  313. blendedLens.FocusDistance = Mathf.Lerp(lensA.FocusDistance, lensB.FocusDistance, t);
  314. #endif
  315. #if CINEMACHINE_HDRP
  316. blendedLens.Iso = Mathf.RoundToInt(Mathf.Lerp((float)lensA.Iso, (float)lensB.Iso, t));
  317. blendedLens.ShutterSpeed = Mathf.Lerp(lensA.ShutterSpeed, lensB.ShutterSpeed, t);
  318. blendedLens.Aperture = Mathf.Lerp(lensA.Aperture, lensB.Aperture, t);
  319. blendedLens.BladeCount = Mathf.RoundToInt(Mathf.Lerp(lensA.BladeCount, lensB.BladeCount, t));;
  320. blendedLens.Curvature = Vector2.Lerp(lensA.Curvature, lensB.Curvature, t);
  321. blendedLens.BarrelClipping = Mathf.Lerp(lensA.BarrelClipping, lensB.BarrelClipping, t);
  322. blendedLens.Anamorphism = Mathf.Lerp(lensA.Anamorphism, lensB.Anamorphism, t);
  323. #endif
  324. return blendedLens;
  325. }
  326. /// <summary>Make sure lens settings are sane. Call this from OnValidate().</summary>
  327. public void Validate()
  328. {
  329. FarClipPlane = Mathf.Max(FarClipPlane, NearClipPlane + 0.001f);
  330. FieldOfView = Mathf.Clamp(FieldOfView, 0.01f, 179f);
  331. m_SensorSize.x = Mathf.Max(m_SensorSize.x, 0.1f);
  332. m_SensorSize.y = Mathf.Max(m_SensorSize.y, 0.1f);
  333. #if UNITY_2022_2_OR_NEWER
  334. FocusDistance = Mathf.Max(FocusDistance, 0.01f);
  335. #endif
  336. #if CINEMACHINE_HDRP
  337. #if CINEMACHINE_HDRP_14
  338. ShutterSpeed = Mathf.Max(0, ShutterSpeed);
  339. Aperture = Mathf.Clamp(Aperture, Camera.kMinAperture, Camera.kMaxAperture);
  340. BladeCount = Mathf.Clamp(BladeCount, Camera.kMinBladeCount, Camera.kMaxBladeCount);
  341. BarrelClipping = Mathf.Clamp01(BarrelClipping);
  342. Curvature.x = Mathf.Clamp(Curvature.x, Camera.kMinAperture, Camera.kMaxAperture);
  343. Curvature.y = Mathf.Clamp(Curvature.y, Curvature.x, Camera.kMaxAperture);
  344. Anamorphism = Mathf.Clamp(Anamorphism, -1, 1);
  345. #else
  346. ShutterSpeed = Mathf.Max(0, ShutterSpeed);
  347. Aperture = Mathf.Clamp(Aperture, HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture);
  348. BladeCount = Mathf.Clamp(BladeCount, HDPhysicalCamera.kMinBladeCount, HDPhysicalCamera.kMaxBladeCount);
  349. BarrelClipping = Mathf.Clamp01(BarrelClipping);
  350. Curvature.x = Mathf.Clamp(Curvature.x, HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture);
  351. Curvature.y = Mathf.Clamp(Curvature.y, Curvature.x, HDPhysicalCamera.kMaxAperture);
  352. Anamorphism = Mathf.Clamp(Anamorphism, -1, 1);
  353. #endif
  354. #endif
  355. }
  356. }
  357. }