using UnityEngine; using System; #if CINEMACHINE_HDRP || CINEMACHINE_LWRP_7_0_0 #if CINEMACHINE_HDRP_7_0_0 using UnityEngine.Rendering.HighDefinition; #else #if CINEMACHINE_LWRP_7_0_0 using UnityEngine.Rendering.Universal; #else using UnityEngine.Experimental.Rendering.HDPipeline; #endif #endif #endif namespace Cinemachine { /// /// Describes the FOV and clip planes for a camera. This generally mirrors the Unity Camera's /// lens settings, and will be used to drive the Unity camera when the vcam is active. /// [Serializable] [DocumentationSorting(DocumentationSortingAttribute.Level.UserRef)] public struct LensSettings { /// Default Lens Settings public static LensSettings Default = new LensSettings(40f, 10f, 0.1f, 5000f, 0); /// /// This is the camera view in vertical degrees. For cinematic people, a 50mm lens /// on a super-35mm sensor would equal a 19.6 degree FOV /// [Range(1f, 179f)] [Tooltip("This is the camera view in vertical degrees. For cinematic people, a 50mm lens " + "on a super-35mm sensor would equal a 19.6 degree FOV")] public float FieldOfView; /// /// When using an orthographic camera, this defines the half-height, in world /// co-ordinates, of the camera view. /// [Tooltip("When using an orthographic camera, this defines the half-height, in world " + "coordinates, of the camera view.")] public float OrthographicSize; /// /// The near clip plane for this LensSettings /// [Tooltip("This defines the near region in the renderable range of the camera frustum. " + "Raising this value will stop the game from drawing things near the camera, which " + "can sometimes come in handy. Larger values will also increase your shadow resolution.")] public float NearClipPlane; /// /// The far clip plane for this LensSettings /// [Tooltip("This defines the far region of the renderable range of the camera frustum. Typically " + "you want to set this value as low as possible without cutting off desired distant objects")] public float FarClipPlane; /// /// The dutch (tilt) to be applied to the camera. In degrees /// [Range(-180f, 180f)] [Tooltip("Camera Z roll, or tilt, in degrees.")] public float Dutch; /// /// This is set every frame by the virtual camera, based on the value found in the /// currently associated Unity camera /// public bool Orthographic { get; set; } /// /// This is set every frame by the virtual camera, based on the value /// found in the currently associated Unity camera /// public Vector2 SensorSize { get; set; } /// /// Sensor aspect, not screen aspect. For nonphysical cameras, this is the same thing. /// public float Aspect { get { return SensorSize.y == 0 ? 1f : (SensorSize.x / SensorSize.y); } } /// /// This is set every frame by the virtual camera, based on the value /// found in the currently associated Unity camera /// public bool IsPhysicalCamera { get; set; } /// For physical cameras only: position of the gate relative to the film back public Vector2 LensShift; #if CINEMACHINE_HDRP public int Iso; public float ShutterSpeed; [Range(HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture)] public float Aperture; [Range(HDPhysicalCamera.kMinBladeCount, HDPhysicalCamera.kMaxBladeCount)] public int BladeCount; public Vector2 Curvature; [Range(0, 1)] public float BarrelClipping; [Range(-1, 1)] public float Anamorphism; #endif /// /// Creates a new LensSettings, copying the values from the /// supplied Camera /// /// The Camera from which the FoV, near /// and far clip planes will be copied. public static LensSettings FromCamera(Camera fromCamera) { LensSettings lens = Default; if (fromCamera != null) { lens.FieldOfView = fromCamera.fieldOfView; lens.OrthographicSize = fromCamera.orthographicSize; lens.NearClipPlane = fromCamera.nearClipPlane; lens.FarClipPlane = fromCamera.farClipPlane; #if UNITY_2018_2_OR_NEWER lens.LensShift = fromCamera.lensShift; #endif lens.SnapshotCameraReadOnlyProperties(fromCamera); #if CINEMACHINE_HDRP if (lens.IsPhysicalCamera) { var pc = new HDPhysicalCamera(); #if UNITY_2019_2_OR_NEWER fromCamera.TryGetComponent(out var hda); #else var hda = fromCamera.GetComponent(); #endif if (hda != null) pc = hda.physicalParameters; lens.Iso = pc.iso; lens.ShutterSpeed = pc.shutterSpeed; lens.Aperture = pc.aperture; lens.BladeCount = pc.bladeCount; lens.Curvature = pc.curvature; lens.BarrelClipping = pc.barrelClipping; lens.Anamorphism = pc.anamorphism; } #endif } return lens; } /// /// Snapshot the properties that are read-only in the Camera /// /// The Camera from which we will take the info public void SnapshotCameraReadOnlyProperties(Camera camera) { if (camera != null) { Orthographic = camera.orthographic; SensorSize = new Vector2(camera.aspect, 1f); #if UNITY_2018_2_OR_NEWER IsPhysicalCamera = camera.usePhysicalProperties; if (IsPhysicalCamera) SensorSize = camera.sensorSize; else LensShift = Vector2.zero; #endif } } /// /// Snapshot the properties that are read-only in the Camera /// /// The LensSettings from which we will take the info public void SnapshotCameraReadOnlyProperties(ref LensSettings lens) { Orthographic = lens.Orthographic; SensorSize = lens.SensorSize; #if UNITY_2018_2_OR_NEWER IsPhysicalCamera = lens.IsPhysicalCamera; if (!IsPhysicalCamera) LensShift = Vector2.zero; #endif } /// /// Explicit constructor for this LensSettings /// /// The Vertical field of view /// If orthographic, this is the half-height of the screen /// The near clip plane /// The far clip plane /// Camera roll, in degrees. This is applied at the end /// after shot composition. public LensSettings( float fov, float orthographicSize, float nearClip, float farClip, float dutch) : this() { FieldOfView = fov; OrthographicSize = orthographicSize; NearClipPlane = nearClip; FarClipPlane = farClip; Dutch = dutch; #if CINEMACHINE_HDRP Iso = 200; ShutterSpeed = 0.005f; Aperture = 16; BladeCount = 5; Curvature = new Vector2(2, 11); BarrelClipping = 0.25f; Anamorphism = 0; #endif } /// /// Linearly blends the fields of two LensSettings and returns the result /// /// The LensSettings to blend from /// The LensSettings to blend to /// The interpolation value. Internally clamped to the range [0,1] /// Interpolated settings public static LensSettings Lerp(LensSettings lensA, LensSettings lensB, float t) { t = Mathf.Clamp01(t); LensSettings blendedLens = new LensSettings(); blendedLens.FarClipPlane = Mathf.Lerp(lensA.FarClipPlane, lensB.FarClipPlane, t); blendedLens.NearClipPlane = Mathf.Lerp(lensA.NearClipPlane, lensB.NearClipPlane, t); blendedLens.FieldOfView = Mathf.Lerp(lensA.FieldOfView, lensB.FieldOfView, t); blendedLens.OrthographicSize = Mathf.Lerp(lensA.OrthographicSize, lensB.OrthographicSize, t); blendedLens.Dutch = Mathf.Lerp(lensA.Dutch, lensB.Dutch, t); blendedLens.Orthographic = lensA.Orthographic && lensB.Orthographic; blendedLens.IsPhysicalCamera = lensA.IsPhysicalCamera || lensB.IsPhysicalCamera; blendedLens.SensorSize = Vector2.Lerp(lensA.SensorSize, lensB.SensorSize, t); blendedLens.LensShift = Vector2.Lerp(lensA.LensShift, lensB.LensShift, t); #if CINEMACHINE_HDRP blendedLens.Iso = Mathf.RoundToInt(Mathf.Lerp((float)lensA.Iso, (float)lensB.Iso, t)); blendedLens.ShutterSpeed = Mathf.Lerp(lensA.ShutterSpeed, lensB.ShutterSpeed, t); blendedLens.Aperture = Mathf.Lerp(lensA.Aperture, lensB.Aperture, t); blendedLens.BladeCount = Mathf.RoundToInt(Mathf.Lerp(lensA.BladeCount, lensB.BladeCount, t));; blendedLens.Curvature = Vector2.Lerp(lensA.Curvature, lensB.Curvature, t); blendedLens.BarrelClipping = Mathf.Lerp(lensA.BarrelClipping, lensB.BarrelClipping, t); blendedLens.Anamorphism = Mathf.Lerp(lensA.Anamorphism, lensB.Anamorphism, t); #endif return blendedLens; } /// Make sure lens settings are sane. Call this from OnValidate(). public void Validate() { if (!Orthographic) NearClipPlane = Mathf.Max(NearClipPlane, 0.001f); FarClipPlane = Mathf.Max(FarClipPlane, NearClipPlane + 0.001f); FieldOfView = Mathf.Clamp(FieldOfView, 0.01f, 179f); #if CINEMACHINE_HDRP ShutterSpeed = Mathf.Max(0, ShutterSpeed); Aperture = Mathf.Clamp(Aperture, HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture); BladeCount = Mathf.Clamp(BladeCount, HDPhysicalCamera.kMinBladeCount, HDPhysicalCamera.kMaxBladeCount); BarrelClipping = Mathf.Clamp01(BarrelClipping); Curvature.x = Mathf.Clamp(Curvature.x, HDPhysicalCamera.kMinAperture, HDPhysicalCamera.kMaxAperture); Curvature.y = Mathf.Clamp(Curvature.y, Curvature.x, HDPhysicalCamera.kMaxAperture); Anamorphism = Mathf.Clamp(Anamorphism, -1, 1); #endif } } }