LensSettings.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. using UnityEngine;
  2. using System;
  3. #if CINEMACHINE_HDRP || CINEMACHINE_LWRP_7_0_0
  4. #if CINEMACHINE_HDRP_7_0_0
  5. using UnityEngine.Rendering.HighDefinition;
  6. #else
  7. #if CINEMACHINE_LWRP_7_0_0
  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 vertical 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 vertical degrees. For cinematic people, a 50mm lens "
  32. + "on a super-35mm sensor would equal a 19.6 degree FOV")]
  33. public float FieldOfView;
  34. /// <summary>
  35. /// When using an orthographic camera, this defines the half-height, in world
  36. /// co-ordinates, of the camera view.
  37. /// </summary>
  38. [Tooltip("When using an orthographic camera, this defines the half-height, in world "
  39. + "coordinates, of the camera view.")]
  40. public float OrthographicSize;
  41. /// <summary>
  42. /// The near clip plane for this LensSettings
  43. /// </summary>
  44. [Tooltip("This defines the near region in the renderable range of the camera frustum. "
  45. + "Raising this value will stop the game from drawing things near the camera, which "
  46. + "can sometimes come in handy. Larger values will also increase your shadow resolution.")]
  47. public float NearClipPlane;
  48. /// <summary>
  49. /// The far clip plane for this LensSettings
  50. /// </summary>
  51. [Tooltip("This defines the far region of the renderable range of the camera frustum. Typically "
  52. + "you want to set this value as low as possible without cutting off desired distant objects")]
  53. public float FarClipPlane;
  54. /// <summary>
  55. /// The dutch (tilt) to be applied to the camera. In degrees
  56. /// </summary>
  57. [Range(-180f, 180f)]
  58. [Tooltip("Camera Z roll, or tilt, in degrees.")]
  59. public float Dutch;
  60. /// <summary>
  61. /// This is set every frame by the virtual camera, based on the value found in the
  62. /// currently associated Unity camera
  63. /// </summary>
  64. public bool Orthographic { get; set; }
  65. /// <summary>
  66. /// This is set every frame by the virtual camera, based on the value
  67. /// found in the currently associated Unity camera
  68. /// </summary>
  69. public Vector2 SensorSize { get; set; }
  70. /// <summary>
  71. /// Sensor aspect, not screen aspect. For nonphysical cameras, this is the same thing.
  72. /// </summary>
  73. public float Aspect { get { return SensorSize.y == 0 ? 1f : (SensorSize.x / SensorSize.y); } }
  74. /// <summary>
  75. /// This is set every frame by the virtual camera, based on the value
  76. /// found in the currently associated Unity camera
  77. /// </summary>
  78. public bool IsPhysicalCamera { get; set; }
  79. /// <summary>For physical cameras only: position of the gate relative to the film back</summary>
  80. public Vector2 LensShift;
  81. #if CINEMACHINE_HDRP
  82. public int Iso;
  83. public float ShutterSpeed;
  84. [Range(HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture)]
  85. public float Aperture;
  86. [Range(HDPhysicalCamera.kMinBladeCount, HDPhysicalCamera.kMaxBladeCount)]
  87. public int BladeCount;
  88. public Vector2 Curvature;
  89. [Range(0, 1)]
  90. public float BarrelClipping;
  91. [Range(-1, 1)]
  92. public float Anamorphism;
  93. #endif
  94. /// <summary>
  95. /// Creates a new LensSettings, copying the values from the
  96. /// supplied Camera
  97. /// </summary>
  98. /// <param name="fromCamera">The Camera from which the FoV, near
  99. /// and far clip planes will be copied.</param>
  100. public static LensSettings FromCamera(Camera fromCamera)
  101. {
  102. LensSettings lens = Default;
  103. if (fromCamera != null)
  104. {
  105. lens.FieldOfView = fromCamera.fieldOfView;
  106. lens.OrthographicSize = fromCamera.orthographicSize;
  107. lens.NearClipPlane = fromCamera.nearClipPlane;
  108. lens.FarClipPlane = fromCamera.farClipPlane;
  109. #if UNITY_2018_2_OR_NEWER
  110. lens.LensShift = fromCamera.lensShift;
  111. #endif
  112. lens.SnapshotCameraReadOnlyProperties(fromCamera);
  113. #if CINEMACHINE_HDRP
  114. if (lens.IsPhysicalCamera)
  115. {
  116. var pc = new HDPhysicalCamera();
  117. #if UNITY_2019_2_OR_NEWER
  118. fromCamera.TryGetComponent<HDAdditionalCameraData>(out var hda);
  119. #else
  120. var hda = fromCamera.GetComponent<HDAdditionalCameraData>();
  121. #endif
  122. if (hda != null)
  123. pc = hda.physicalParameters;
  124. lens.Iso = pc.iso;
  125. lens.ShutterSpeed = pc.shutterSpeed;
  126. lens.Aperture = pc.aperture;
  127. lens.BladeCount = pc.bladeCount;
  128. lens.Curvature = pc.curvature;
  129. lens.BarrelClipping = pc.barrelClipping;
  130. lens.Anamorphism = pc.anamorphism;
  131. }
  132. #endif
  133. }
  134. return lens;
  135. }
  136. /// <summary>
  137. /// Snapshot the properties that are read-only in the Camera
  138. /// </summary>
  139. /// <param name="camera">The Camera from which we will take the info</param>
  140. public void SnapshotCameraReadOnlyProperties(Camera camera)
  141. {
  142. if (camera != null)
  143. {
  144. Orthographic = camera.orthographic;
  145. SensorSize = new Vector2(camera.aspect, 1f);
  146. #if UNITY_2018_2_OR_NEWER
  147. IsPhysicalCamera = camera.usePhysicalProperties;
  148. if (IsPhysicalCamera)
  149. SensorSize = camera.sensorSize;
  150. else
  151. LensShift = Vector2.zero;
  152. #endif
  153. }
  154. }
  155. /// <summary>
  156. /// Snapshot the properties that are read-only in the Camera
  157. /// </summary>
  158. /// <param name="lens">The LensSettings from which we will take the info</param>
  159. public void SnapshotCameraReadOnlyProperties(ref LensSettings lens)
  160. {
  161. Orthographic = lens.Orthographic;
  162. SensorSize = lens.SensorSize;
  163. #if UNITY_2018_2_OR_NEWER
  164. IsPhysicalCamera = lens.IsPhysicalCamera;
  165. if (!IsPhysicalCamera)
  166. LensShift = Vector2.zero;
  167. #endif
  168. }
  169. /// <summary>
  170. /// Explicit constructor for this LensSettings
  171. /// </summary>
  172. /// <param name="fov">The Vertical field of view</param>
  173. /// <param name="orthographicSize">If orthographic, this is the half-height of the screen</param>
  174. /// <param name="nearClip">The near clip plane</param>
  175. /// <param name="farClip">The far clip plane</param>
  176. /// <param name="dutch">Camera roll, in degrees. This is applied at the end
  177. /// after shot composition.</param>
  178. public LensSettings(
  179. float fov, float orthographicSize,
  180. float nearClip, float farClip, float dutch) : this()
  181. {
  182. FieldOfView = fov;
  183. OrthographicSize = orthographicSize;
  184. NearClipPlane = nearClip;
  185. FarClipPlane = farClip;
  186. Dutch = dutch;
  187. #if CINEMACHINE_HDRP
  188. Iso = 200;
  189. ShutterSpeed = 0.005f;
  190. Aperture = 16;
  191. BladeCount = 5;
  192. Curvature = new Vector2(2, 11);
  193. BarrelClipping = 0.25f;
  194. Anamorphism = 0;
  195. #endif
  196. }
  197. /// <summary>
  198. /// Linearly blends the fields of two LensSettings and returns the result
  199. /// </summary>
  200. /// <param name="lensA">The LensSettings to blend from</param>
  201. /// <param name="lensB">The LensSettings to blend to</param>
  202. /// <param name="t">The interpolation value. Internally clamped to the range [0,1]</param>
  203. /// <returns>Interpolated settings</returns>
  204. public static LensSettings Lerp(LensSettings lensA, LensSettings lensB, float t)
  205. {
  206. t = Mathf.Clamp01(t);
  207. LensSettings blendedLens = new LensSettings();
  208. blendedLens.FarClipPlane = Mathf.Lerp(lensA.FarClipPlane, lensB.FarClipPlane, t);
  209. blendedLens.NearClipPlane = Mathf.Lerp(lensA.NearClipPlane, lensB.NearClipPlane, t);
  210. blendedLens.FieldOfView = Mathf.Lerp(lensA.FieldOfView, lensB.FieldOfView, t);
  211. blendedLens.OrthographicSize = Mathf.Lerp(lensA.OrthographicSize, lensB.OrthographicSize, t);
  212. blendedLens.Dutch = Mathf.Lerp(lensA.Dutch, lensB.Dutch, t);
  213. blendedLens.Orthographic = lensA.Orthographic && lensB.Orthographic;
  214. blendedLens.IsPhysicalCamera = lensA.IsPhysicalCamera || lensB.IsPhysicalCamera;
  215. blendedLens.SensorSize = Vector2.Lerp(lensA.SensorSize, lensB.SensorSize, t);
  216. blendedLens.LensShift = Vector2.Lerp(lensA.LensShift, lensB.LensShift, t);
  217. #if CINEMACHINE_HDRP
  218. blendedLens.Iso = Mathf.RoundToInt(Mathf.Lerp((float)lensA.Iso, (float)lensB.Iso, t));
  219. blendedLens.ShutterSpeed = Mathf.Lerp(lensA.ShutterSpeed, lensB.ShutterSpeed, t);
  220. blendedLens.Aperture = Mathf.Lerp(lensA.Aperture, lensB.Aperture, t);
  221. blendedLens.BladeCount = Mathf.RoundToInt(Mathf.Lerp(lensA.BladeCount, lensB.BladeCount, t));;
  222. blendedLens.Curvature = Vector2.Lerp(lensA.Curvature, lensB.Curvature, t);
  223. blendedLens.BarrelClipping = Mathf.Lerp(lensA.BarrelClipping, lensB.BarrelClipping, t);
  224. blendedLens.Anamorphism = Mathf.Lerp(lensA.Anamorphism, lensB.Anamorphism, t);
  225. #endif
  226. return blendedLens;
  227. }
  228. /// <summary>Make sure lens settings are sane. Call this from OnValidate().</summary>
  229. public void Validate()
  230. {
  231. if (!Orthographic)
  232. NearClipPlane = Mathf.Max(NearClipPlane, 0.001f);
  233. FarClipPlane = Mathf.Max(FarClipPlane, NearClipPlane + 0.001f);
  234. FieldOfView = Mathf.Clamp(FieldOfView, 0.01f, 179f);
  235. #if CINEMACHINE_HDRP
  236. ShutterSpeed = Mathf.Max(0, ShutterSpeed);
  237. Aperture = Mathf.Clamp(Aperture, HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture);
  238. BladeCount = Mathf.Clamp(BladeCount, HDPhysicalCamera.kMinBladeCount, HDPhysicalCamera.kMaxBladeCount);
  239. BarrelClipping = Mathf.Clamp01(BarrelClipping);
  240. Curvature.x = Mathf.Clamp(Curvature.x, HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture);
  241. Curvature.y = Mathf.Clamp(Curvature.y, Curvature.x, HDPhysicalCamera.kMaxAperture);
  242. Anamorphism = Mathf.Clamp(Anamorphism, -1, 1);
  243. #endif
  244. }
  245. }
  246. }